linker - 为什么编译器不能阻止多个定义包含?

  显示原文与译文双语对照的内容
95 4

我有一个头文件 x.h,它包含在多个 *.c 源文件中。这个头文件定义了一些结构变量。

我已经在头文件的开头放置了多个防包含保护,如下所示:

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

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

在头文件顶部不会阻止多重包含保护,防止多次包含头文件 x.h,从而避免在 x.h 文件中多次定义变量的定义。

#pragma 在这个特定编译器上不工作,那么解决方案是什么?有人给发了个类似的问题。这对我似乎不起作用。这里解决方案的工作原理?

时间:原作者:0个回答

90 2

如果链接器抱怨,它意味着你有定义而不仅仅是你的头中的声明。下面是一个错误的例子。

#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; 
原作者:
80 3

使用包含保护防止一个编译单元包含两次标题。如果头文件包含 A.h 和 B.cpp,则在编译 B.cpp 中声明 A.h 和 B.h, everything如果你不使用包含保护程序,则在编译中声明 twice 。

你的包括防止这种情况发生,直到现在为止。

但是在链接时获得多个定义,换句话说,两个编译单元定义,这可以能意味着在头中使用,。

原作者:
62 2

头保护只适用于单个编译单元 换句话说,源文件。如果多次包含头文件,可以能是因为 main.c 中包含的所有头都包含 stdio.h,然后保护将帮助。

如果在 x.h 中包含函数 f的定义( 包括 main.cutil.c ),那么在创建 main.o 并将它的用于 util.c 创建 util.o 时,就像将 f 定义复制并粘贴到 main.c 中一样。然后链接者会抱怨,这会发生,尽管你。main.c 中有多个 #include"x.h" 语句是可能的,因为这些保护。

原作者:
94 1

如果函数不大,则可以在它们之前使用"行内",而链接器不会发出警告。

原作者:
118 4

使用多重包含保护防止编译器编译时错误,但你会得到一个链接器错误。头文件中是否有不使用 extern的数据定义?

原作者:
79 3

也许 X_H 已经在其他地方定义了?我刚刚遇到了这个问题,其中Xlib在/usr/include/X11/X.h. 中定义了 X_H

要检查,可以调用 gcc -dM -E ( 如果你正在使用 gcc ),比如 我使用的buildsystem中CC=gcc CFLAGS="-dM -E" make如果输出文件包含 #define X_H,即使你从文件( 使用 Y_H 例如) 移除它,则它已经在源代码之外定义。

原作者:
...