为什么我的编译保护不能防止多个定义包含?

gol*_*ean 45 c linker multiple-inclusions

我有一个头文件xh,它包含多个*.c源文件.此头文件定义了一些结构变量.

我在头文件的开头添加了多个包含防护措施:

#ifndef X_H
#define X_H
...
..
//header file declarations and definitons.


#endif//X_H
Run Code Online (Sandbox Code Playgroud)

在构建时,我得到与多个定义相关的链接器错误.我理解这个问题.

  1. 不会像我一样在头文件的顶部有多重包含防护,防止头文件xh的多个包含,从而避免xh中存在的变量的多个定义?

  2. #pragma曾经不适用于这个特定的编译器,那么解决方案是什么?有人把这个答案发给了一个类似的问题.它似乎对我不起作用.这个解决方案如何运作?

Rod*_*ddy 57

如果链接器抱怨,则意味着您的标头中有定义而不仅仅是声明.这是一个错误的例子.

#ifndef X_H
#define X_H

int myFunc()
{
  return 42; // Wrong! definition in header.
}

int myVar; // Wrong! definition in header.

#endif
Run Code Online (Sandbox Code Playgroud)

您应该将其拆分为源文件和头文件,如下所示:

标题:

#ifndef X_H
#define X_H

extern int myFunc();

extern int myVar; 

#endif
Run Code Online (Sandbox Code Playgroud)

C来源:

int myFunc()
{
  return 42; 
}

int myVar; 
Run Code Online (Sandbox Code Playgroud)


Pie*_*ter 14

使用include guard可防止一个编译单元包含两次头文件.例如,如果标题Bh包含Ah而B.cpp包含Ah和Bh,那么如果你没有使用包含保护,那么来自Ah的所有内容都将在编译B.cpp中声明两次.

你的包含警卫可以防止这种情况发生,一切都很好,直到现在.

但是你在链接时获得了多个定义,即两个编译单元定义相同的东西,这可能意味着你在头文件中有一个真正的定义,对所有变量使用extern,确保函数是内联的或在cpp文件中定义.


per*_*eal 12

标头保护仅适用于单个编译单元,即源文件.如果你碰巧有一个头文件多次,也许是因为所有的标题从包括main.c依次包括stdio.h然后守卫会有所帮助.

如果你有一个函数的定义fx.h是由包括main.cutil.c,那么它就像复制和粘贴的定义fmain.c创建时main.o,做了同样的util.c创造util.o.然后链接器会抱怨,尽管你的标题守卫发生了这种情况.当然,由于这些警卫,可以有多个#include "x.h"陈述main.c.


ncl*_*ent 7

如果函数不大,可以在它们之前使用"inline",链接器不会抱怨.


Gre*_*ill 2

使用多重包含保护可以防止编译器错误,但您会收到链接器错误。头文件中是否有不使用的数据定义extern