C 为什么不';我的编译保护不能阻止多个定义包含吗?
我有一个头文件x.h,它包含在多个*.c源文件中。 此头文件定义了一些结构变量 我在头文件的开头放置了多个包含预防保护,如下所示:C 为什么不';我的编译保护不能阻止多个定义包含吗?,c,linker,multiple-inclusions,C,Linker,Multiple Inclusions,我有一个头文件x.h,它包含在多个*.c源文件中。 此头文件定义了一些结构变量 我在头文件的开头放置了多个包含预防保护,如下所示: #ifndef X_H #define X_H ... .. //header file declarations and definitons. #endif//X_H 在构建时,我得到与多个定义相关的链接器错误。我理解这个问题 在头文件的顶部有一个多重包含防止保护,难道不会像我一样,防止头文件x.h的多重包含,从而避免x.h中存在的变量的多重定义吗 #pr
#ifndef X_H
#define X_H
...
..
//header file declarations and definitons.
#endif//X_H
在构建时,我得到与多个定义相关的链接器错误。我理解这个问题
#pragma
once在这个特定的编译器上不起作用,那么解决方案是什么呢?
有人发布了一个类似问题的答案。这似乎对我不起作用。这个解决方案是如何工作的使用多重包含保护可以防止编译器错误,但会出现链接器错误。头文件中是否有不使用
extern
的数据定义?使用include-guard可防止一个编译单元将头包含两次。例如,如果标题B.h包括A.h,而B.cpp包括A.h和B.h,那么如果您没有使用include-guard,则从A.h开始的所有内容都将在编译B.cpp中声明两次
你的警卫阻止了这一切的发生,直到现在一切都很好
但是在链接时会得到多个定义,即两个编译单元定义同一个东西,这可能意味着您的头中有一个真正的定义,对所有变量使用extern,确保函数是内联的或是在cpp文件中定义的。如果链接器抱怨,这意味着您在头中有定义,而不仅仅是声明。这是一个错误的例子
#ifndef X_H
#define X_H
int myFunc()
{
return 42; // Wrong! definition in header.
}
int myVar; // Wrong! definition in header.
#endif
您应该将其拆分为源文件和头文件,如下所示:
标题:
#ifndef X_H
#define X_H
extern int myFunc();
extern int myVar;
#endif
C资料来源:
int myFunc()
{
return 42;
}
int myVar;
如果函数不大,可以在它们前面使用“inline”,链接器不会抱怨。头保护只适用于单个编译单元,即源文件。如果您碰巧多次包含头文件,可能是因为
main.c
中包含的所有头文件依次包含stdio.h
,那么guards将提供帮助
如果在
main.c
和util.c
中包含函数f
的定义,那么这就像在创建main.o
时将f
的定义复制并粘贴到main.c
中,并对util.c
执行相同操作以创建util.o
。然后,链接器会抱怨,尽管你的标题有防护,这种情况还是会发生。在main.c
中有多个#include“x.h”
语句当然是可能的,因为有了这些保护。也许x#h
已经在其他地方定义了?我刚刚遇到了这个问题,其中Xlib在/usr/include/X11/X.H中定义了X_H
要检查,您可以调用
gcc-dM-E
(如果您使用的是gcc),例如,在我使用的构建系统中,它与CC=gcc CFLAGS=“-dM-E”make
一起工作。如果输出文件包含#define X_H
,即使您将其从文件中删除(例如使用Y_H
),则它已在源代码之外定义。int myVar;'充其量只是一个初步的定义;它通常不会引起麻烦。如果有初始值设定项,它会。不过,我总是使用一个显式的extern,正如你在“固定”版本中所展示的那样。@Jonathan:在C标准中有“暂定定义”这样的东西吗??我认为这样的多个定义会导致“未定义的行为”,但在许多编译器/链接器(gcc…)中,您得到的行为实际上是您想要的!是否可能有一个函数的内联声明紧跟着它的定义?+1表示正确。一些相关问题的答案没有做到这一点,因此提供了技术上不正确的信息。@Stephen:如果您已经在编辑问题标题,请同时查看正文(可能还有标签,但不在这里)。这避免了重复编辑(和颠簸)。@保罗错过了,但我一直在努力观察,谢谢提醒!很久以来我一直有这种怀疑!您的解释澄清了这一点:-)如果已经定义了include-guard,他将得到一个关于无定义的错误,而不是多个定义的错误,对吗?