Linux C 头文件互相包含问题

头文件相互包含的问题
问题:

头文件交叉包含是否会导致递归包含,导致编译出错?
如果不会因为递归包含出错,那么交叉包含是不是完全没问题?
1.1 头文件交叉包含是否会导致递归包含,导致编译出错?(无#ifndef)
  假若头文件a包含了头文件b、头文件b又包含了头文件a,那么在#include头文件a的时候,就可能会导致递归包含,从而导致编译出错;

/* a.h */
#include "b.h"
#define A_H 1

/* b.h */
#include "a.h"
#define B_H 2

/* main.c */
#include <stdlib.h>
#include <stdio.h>
#include "a.h"
#include "b.h"

void main()
{
    printf("hello world!\n");
}

在Visual Studio中会提示,头文件包含了自身;编译时会报错:
fatal error C1014: 包含文件太多 : 深度 = 1024
在Ubuntu下面编译会报错:
a.h:1:15: error: #include nested too deeply
b.h:1:15: error: #include nested too deeply
1.2头文件交叉包含是否会导致递归包含,导致编译出错?(有#ifndef)
  修改a.h、b.h两个文件,main.c文件内容不变。此时编译正常通过:因此可以知道,当头文件相互包含时,只要有预处理#ifndef就可以保证理论上不会出错。

/* a.h */
#ifdef __A_H_
#define __A_H

#include "b.h"
#define A_H 1

#endif

/* b.h */
#ifndef __B_H_
#define __B_H

#include "a.h"
#define B_H 2

#endif

1.3 如果不会因为递归包含出错,那么交叉包含是不是完全没问题?
  从上面的头文件内容可以看出,虽然两个头文件相互包含,但是两个头文件内容并不相互引用。因此编译不会出现问题。但是如果像下面文件,头文件变量又相互引用,则编译会出现变量未知错误

a.h:9:9: error: unknown type name ‘B_H’

/* a.h */
#ifndef __A_H_
#define __A_H_
#include "b.h"

typedef struct _A_H{
    int a;
} A_H;

int fun(B_H *ptr);

#endif

/* b.h */
#ifndef __B_H_
#define __B_H_
#include "a.h"

typedef struct _B_H{
    A_H b;
} B_H;

#endif

/* main.c */
#include <stdio.h>
#include "b.h"
#define CC DD
#define DD 2

void main()
{
    printf("hello world!\n");
}

  使用 ‘gcc -E main.c > tmp’ 将main.c只做预处理,可以看到预处理后的文件内容为:所以是因为变量定义的顺序问题导致问题。

/* tmp 部分内容*/
# 1 "b.h" 1
# 4 "a.h" 2

typedef struct _A_H{
 int a;
} A_H;

int fun(B_H *ptr);
# 4 "b.h" 2

typedef struct _B_H{
 A_H b;
} B_H;
# 3 "main.c" 2

int main()
{
 printf("hello world!\n");
 return 0;
}

1.4 但是将b.h文件中的结构体加上struct又可以编译成功了!!!
此时会出现警告:结构体隐性申明

a.h:9:16: warning: ‘struct _B_H’ declared inside parameter list [enabled by default]

/* a.h */
#ifndef __A_H_
#define __A_H_
#include "b.h"

typedef struct _A_H{
    int a;
} A_H;

int fun(struct _B_H *ptr);

#endif

/* b.h */
#ifndef __B_H_
#define __B_H_
#include "a.h"

typedef struct _B_H{
    struct _A_H b;
} B_H;

#endif

总结
  头文件相互包含,而且变量又相互引用。此时应该将其中一个头文件拆成两个头文件b1.h、b2.h,b1.h让原来的a.h包含;b2.h用来包含a.h。不要使两个头文件变量相互引用引用的设计方式出现。

从上面main.c内容可以看出宏定义的顺序可以不按顺序出现,编译也不会出错。
--------------------- 
作者:zyz394515661 
来源:CSDN 
原文:https://blog.csdn.net/zyz394515661/article/details/83218462 
版权声明:本文为博主原创文章,转载请附上博文链接!

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值