了解链接器的原点重复符号错误 [英] Understanding the origin of a linker duplicate symbol error

查看:218
本文介绍了了解链接器的原点重复符号错误的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个以前编译的c ++程序,但是在使用Jamfiles之后,程序不再编译并且 ld 发出了一个重复的符号错误。这种情况持续发生在之后恢复到原始的Jamfiles,运行 bjam clean ,手动删除对象,并从gcc前端切换到gcc 4.2.1 .7。

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.

程序的简单描述是有 main.cpp 和四个文件 ah,cpp bh,cpp ,它们被编译成一个静态库,链接到 main.o main.cpp b.cpp 都取决于包含违规符号的文件, off.h ,通过两个不同的中间文件,但 ah a.cpp 在任何方式依赖 off.h

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.

在您提出之前,我确保所有文件多个定义保护( #ifndef #define #endif ),虽然我发现一个文件丢失了它,它没有引用 off.h 。更重要的是, bh 不包括引用 off.h 的任何内容,只有实现 b.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.

要添加我的混淆,我可以从<$ c $中删除 off.h 的引用c> b.cpp ,并且如预期的那样重新编译成功。但是,当我添加参考回来,它也编译成功,并继续这样做后清理出目标文件。我仍然失去了为什么它没有编译,特别是考虑到符号不应该冲突,我已经防止了符号重复,我已经摆脱了任何先前/不完整的构建。

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.

因为我能够成功地编译我的程序,我怀疑我能够重现它来测试任何建议。但是,我很好奇这将如何发生,如果我在未来遇到这种行为,如果什么,除了我已经做了,我可以做修复它吗?

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?

推荐答案

这通常是在头文件中定义对象的结果,而不是仅仅声明它。请考虑:

This is often the result of defining an object in a header file, rather than merely declaring it. Consider:

hh

#ifndef H_H_
#define H_H_
int i;
#endif

a.cpp

#include "h.h"


$ b b

b.cpp

#include "h.h"
int main() {}

这将产生一个重复的符号 i 。解决方案是在头文件中声明对象: extern int i; 并在一个源代码文件中定义它: int i;

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;.

这篇关于了解链接器的原点重复符号错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆