rco*_*yer 21 c++ linker gcc clang
我有一个先前编译过的c ++程序,但是在使用Jamfiles之后,程序不再编译并ld
发出了一个duplicate symbol error
.在连续恢复到最初的Jamfiles,运行bjam clean
,手动移除对象,并从gcc前端的clang切换到MacO 10.6.7上的gcc 4.2.1 之后,这种情况持续存在.
该程序的简化描述是有main.cpp
四个文件,a.h,cpp
并且b.h,cpp
被编译成链接到的静态库main.o
.两者,main.cpp
并且b.cpp
依赖于包含违规符号的文件off.h
,通过两个不同的中间文件,但既不以任何方式a.h
也不a.cpp
依赖off.h
.
你问之前,我确信,所有文件都被包裹在多个定义卫士(#ifndef
,#define
,#endif
),虽然我没有发现失踪了他们一个文件,它并没有提及off.h
.更重要的是,b.h
不包括引用的任何内容off.h
,只有实现,b.cpp
引用任何引用off.h
.仅此一点让我感到困惑.
为了增加我的困惑,我能够删除对off.h
from 的引用,b.cpp
并且正如预期的那样,它已成功重新编译.但是,当我添加引用时,它也成功编译,并在清除目标文件后继续这样做.我仍然不知道为什么它没有编译,特别是考虑到符号不应该有冲突,我已经阻止了符号重复,我已经摆脱了任何先前/不完整的构建.
由于我能够成功编译我的程序,我怀疑我是否能够重现它以测试任何建议.但是,我很好奇这是如何发生的,如果我将来遇到这种行为,除了我所做的以外什么,我可以做些什么来修复它?
Rob*_*obᵩ 47
这通常是在头文件中定义对象的结果,而不是仅仅声明它.考虑:
......:
#ifndef H_H_
#define H_H_
int i;
#endif
Run Code Online (Sandbox Code Playgroud)
a.cpp:
#include "h.h"
Run Code Online (Sandbox Code Playgroud)
b.cpp:
#include "h.h"
int main() {}
Run Code Online (Sandbox Code Playgroud)
这将产生一个重复的符号i
.解决方案是在头文件中声明对象:extern int i;
并在其中一个源代码文件中定义它:int i;
.