我用了#ifndef...#define...#endif结构为什么无法避免重复包含?
最近编写一个程序中,我用了#ifndef...#define...#endif结构为什么无法避免重复包含?整个程序中将各种外部芯片各自形成一个头文件和一个C文件,其中一个文件是PCF8563.H,在这个文件里面已经加入了避免重复包含的宏定义,并且在头文件中定义了一些变量和一些函数说明。在相应的PCF8563.C里面包含了这个头文件和主文件里面(文件名是MAIN.C)也包含了这个头文件,这时候没问题,但有另外一个文件里面ADS1110.H里面也要用到PCF8563.H这个头文件,一旦包含了这个文件就出错!不知道为什么! 注意声明和定义,如果变量是私有的就在.c中声明和定义。 应该不是这个原因,因为在头文件里面有不少的变量定义,但只有前面的一个变量出现问题,一旦把那个变量注释掉就好了(不过会出现变量未定义的错误) 变量定义不能或者说不应该定义在.h文件中,例如 有 a.h,里面定义了变量 int temp; 如下:
// a.h
#ifndef _a_h_
#define _a_h_
int temp; // define varible
#endif
// 工程包含两个模块 a.c ,b.c
//--------b.c----------
#include"a.h"
...
//显然编译器编译b.c的时候符号_a_h_没有定义,则temp 变量在b.c里定义了一次
// -------a.c ----------
#include "a.h"
//编译器是独立编译b.c和a.c的,甚至编译顺序都是不确定的,所以编译器编译每个.c文件的时候符号定义都是独立的,
//这时候,仍然 没有定义 _a_h_ 这个符号,则文件a.h再次被a.c包含, temp变量再次定义,但编译仍然没有问题.
// 下面链接器link开始工作,链接b.obj和a.obj,结果有两个temp变量 ,link error!
不知道楼主的问题是不是这个原因?
另外:
#ifndef#define ,else ,... #endif 结构是用来避免以下情况的重复包含的,而不是为上面所说情况准备的
--------------------------------------------------------------
//--- a.h
#ifndef _a_h
#define _a_h
declaration in a
#endif
// end of a.h
------------------------------------------------------------------
//---- b.h
#ifndef _b_h
#define _b_h
#include "a.h" // 注意这里
declaration in b
#endif
// end of b.h
---------------------------------------------------------
//---a.c
#include "a.h"
#include "b.h"
// end of a.c
展开为以下内容:
------------------------------------------------------------
#ifndef _a_h
#define _a_h
declaration in a //定义了符号 _a_h
#endif
#ifndef _b_h
#define _b_h
#ifndef _a_h // 已经定义了 _a_h
#define _a_h
declaration in a // 这行才是重复的,失去作用了
#endif
declaration in b // b.h中的声明
#endif 刚拜读过“shark”帖子,受益,谢谢! shark讲得不错
#ifndef#define ,else ,... #endif 只能解决单个c文件重复包含一个h文件的问题
如果在h文件定义了变量,即使在h文件中加上了#ifndef#define ,else ,... #endif ,当此h文件被多个c文件包含还是会出现重复定义的错误,#ifndef#define ,else ,... #endif 不是解决这种问题的
所以把变量和函数的定义都写在c文件中,h文件中仅仅作变量和函数的声明,h文件中再加上#ifndef#define ,else ,... #endif ,即不会出现重定义的问题了。。。 MARK 重新认识了防重新包含,顶。 shark MARK! mark,学习了 学习一下.... Mark ,学习了 是不是把函数定义到头文件里面了?? 为shark的讲解配幅图 傻孩子,把你书里面讲解这个内容的页面截过来吧 不过ICC好像能自动解决重复包含的问题
编译能通过,但是有warning会指出这些问题
页:
[1]