C++ 了解链接器重复符号错误的起源
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/6116188/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Understanding the origin of a linker duplicate symbol error
提问by rcollyer
I have a c++ program that compiled previously, but after mucking with the Jamfiles, the program no longer compiled and ld
emitted a duplicate symbol error
. This persisted after successively reverting to the original Jamfiles, running bjam clean
, removing the objects by hand, and switching from clang with the gcc front end to gcc 4.2.1 on MacOs 10.6.7.
我有一个以前编译过的 c++ 程序,但是在使用 Jamfiles 之后,该程序不再编译并ld
发出duplicate symbol error
. 在连续恢复到原始 Jamfiles、运行bjam clean
、手动删除对象以及从带有 gcc 前端的 clang 切换到 MacOs 10.6.7 上的 gcc 4.2.1之后,这种情况仍然存在。
A simplified description of the program is that there is main.cpp
and four files, a.h,cpp
and b.h,cpp
, which are compiled into a static library which is linked to main.o
. Both, main.cpp
and b.cpp
depend on the file containing the offending symbol, off.h
, through two different intermediate files, but neither a.h
nor a.cpp
depend in any way on off.h
.
该程序的一个简化描述是有main.cpp
四个文件a.h,cpp
和b.h,cpp
,它们被编译成一个链接到main.o
. 两者,main.cpp
并且b.cpp
取决于包含冒犯符号的文件off.h
,通过两个不同的中间文件,但既不a.h
也不a.cpp
依赖于任何方式off.h
。
Before you ask, I made sure that all files were wrapped in multiple definition guards (#ifndef
, #define
, #endif
), and while I did find a file that was missing them, it did not reference off.h
. More importantly, b.h
does not include anything that references off.h
, only the implementation, b.cpp
, makes any reference to off.h
. This alone had me puzzled.
在您询问之前,我确保所有文件都包含在多个定义保护 ( #ifndef
, #define
, #endif
) 中,虽然我确实找到了缺少它们的文件,但它没有引用off.h
. 更重要的是,b.h
不包括任何引用off.h
,只有实现,b.cpp
,对 进行任何引用off.h
。仅此一点就让我感到困惑。
To add to my confusion, I was able to remove the reference to off.h
from b.cpp
and, as expected, it recompiled successfully. However, when I added the reference back in, it also compiled successfully, and continued to do so after cleaning out the object files. I am still at a loss for why it was failing to compile, especially considering that the symbols should not have conflicted, I had prevented symbol duplication, and I had gotten rid of any prior/incomplete builds.
更让我困惑的是,我能够删除对off.h
from的引用,b.cpp
并且正如预期的那样,它重新编译成功。但是,当我重新添加引用时,它也编译成功,并在清除目标文件后继续编译。我仍然不知道为什么它无法编译,特别是考虑到符号不应该发生冲突,我已经防止了符号重复,并且我已经摆脱了任何先前/不完整的构建。
Since I was able to successfully compile my program, I doubt I'll be able to reproduce it to test out any suggestions. However, I am curious as to how this can happen, and if I run across this behavior in the future, what, if anything beyond what I've done, might I do to fix it?
由于我能够成功编译我的程序,我怀疑我是否能够重现它以测试任何建议。但是,我很好奇这是如何发生的,如果我将来遇到这种行为,如果超出我所做的任何事情,我可以做些什么来解决它?
回答by Rob?
This is often the result of defining an object in a header file, rather than merely declaring it. Consider:
这通常是在头文件中定义对象的结果,而不是仅仅声明它。考虑:
h.h:
哈:
#ifndef H_H_
#define H_H_
int i;
#endif
a.cpp:
a.cpp:
#include "h.h"
b.cpp:
b.cpp:
#include "h.h"
int main() {}
This will produce a duplicate symbol i
. The solution is to declare the object in the header file: extern int i;
and to define it in exactly one of the source-code files: int i;
.
这将产生一个重复的符号i
。解决方案是在头文件中声明对象:extern int i;
并在源代码文件之一中定义它:int i;
.