链接器不指出错误;多个定义警告指向同一行

Posted

技术标签:

【中文标题】链接器不指出错误;多个定义警告指向同一行【英文标题】:Linker does not point out errors; multiple definition warnings pointed to the same line 【发布时间】:2013-12-08 10:50:21 【问题描述】:

相信我,我在这里浏览过好几篇文章,但没有一篇文章解决了我遇到的问题。我有这个运行了 2 年的程序。我正在恢复它,但由于某种原因它现在无法运行。

很明显,我有多个定义(太多了):

============================= 终端输出================= =============

build_files/LinkedStack.o: In function `LinkedStack':
/home/owner/workspace/opencv-galaxies/utilities/structures/LinkedStack.cpp:12: multiple definition of `LinkedStack::LinkedStack()'
build_files/LinkedStack.o:/home/owner/workspace/opencv-galaxies/utilities/structures/LinkedStack.cpp:12: first defined here

... 以此类推,以此类推,... 这一切都以:

collect2: ld returned 1 exit status
make: *** [executables/Assignment3.out] Error 1

================================================ ==========================

奇怪的是,链接器并没有在广泛的警告列表中指出任何错误,更不用说这些不是真正的多重定义。请注意,“多个...-首次定义...”对中的每个警告都指的是同一行。现在我不知道该怎么办了。

我想知道这是否与我们的 makefile 相当繁忙的语法有关(虽然它看起来对我来说真的很好):

================================MAKEFILE =============== ===================

CFLAGS = -g -Wno-deprecated

OBJECTS = utilities/basic/image.h build_files/image.o build_files/ReadImage.o build_files/ReadImageHeader.o build_files/WriteImage.o build_files/LinkedStack.o build_files/unsortedList.o build_files/region.o build_files/Main.o

executables/Assignment3.out: $(OBJECTS)
    g++ $(OBJECTS) -o executables/Assignment3.out build_files/*.o $(CFLAGS) -lncurses

...

build_files/LinkedStack.o:  utilities/structures/LinkedStack.h utilities/structures/LinkedStack.cpp
    g++ -c $(CFLAGS) utilities/structures/LinkedStack.cpp -o build_files/LinkedStack.o

...

clean:
            rm build_files/*.o executables/Assignment3.out

================================================ ============================

所以,这些是我的问题:1)为什么链接器会看到错误以及 2)为什么我有这么多多个定义?

如果您想澄清一下,即使您对发生的事情有所了解,也请告诉我。

=============================== 代码示例 =============== ===============

这是完整的示例函数(我不想让它太长):

//constructor
LinkedStack::LinkedStack()

    topPtr = NULL; //set top pointer to null

================================================ ==========================

【问题讨论】:

缩小范围并发布代码的精简版本 - 使用 1 个方法保留类。 @LuchianGrigore :我应该对 makefile 做同样的事情吗? 那些错误,而不是警告(即使它没有说“错误:多重定义......”)。现在,请想象您自己是另一个 SO 用户(像我一样),您不希望看到一些 实际代码(C++ 代码)能够提供帮助吗? (另见sscce.org)因为目前我们能做的最好的就是盲目猜测(比如,“你没有在标题中包含 .cpp 文件,是吗?”)... @gx_ :对不起;我只是觉得我给的就足够了。无论如何,帖子已更新。回答你的问题,不;它是.cpp文件中包含的头文件,即.cpp文件中的#include "LinkedStack.h" @gx_:我不认为这是盲目的猜测。我认为这是事实。 【参考方案1】:

您很可能包含一个在多个翻译单元中实现非内联方法的标头。 Makefile 与它无关。您需要找到方法的定义,并查看它们最终是如何被包含到多个文件中的。如果它们实际上在头文件中,最简单的解决方法可能是将它们全部设为inline

编译器看不到您将标头包含在多个翻译单元中,因为它总是一次只处理一个。当链接器看到各种目标文件时,它只会看到同一事物的许多定义并抱怨。不过,我会认为链接器指针位于定义的位置。

【讨论】:

谢谢。我看到我的伙伴做了一些毫无根据的愚蠢更改,例如将一个类的 .h 和 .cpp 都包含到另一个类的 .h 中。这可能是原因。【参考方案2】:

鉴于您提供的信息,甚至很难猜出问题所在。但是,请确保 a) 您没有在另一个 cpp/h 文件中包含任何 cpp 文件。 b)您在 h 文件中定义的任何实现都是内联的。 (我猜 b 是你的问题)

【讨论】:

您还建议我包括哪些内容以使您的工作更轻松?因为我在看sscce,答案对我来说并不是那么明显。 你检查了我提到的两件事吗? 正如我对 Dietmar 的回答所评论的那样,肯定有 (a),不必要的包含,但没有 (b),没有实现内联函数……。 在您对 Dietmar 的回答中,您说您的合作伙伴将一个类的 cpp 包含到另一个类的 h 文件中。除非我没听懂你,否则这是你的问题! cpp 将在包含该 h 文件的每个翻译单元中编译,导致多个定义。

以上是关于链接器不指出错误;多个定义警告指向同一行的主要内容,如果未能解决你的问题,请参考以下文章

叮当声:警告:-l *:“链接器”输入未使用

jQuery 选择器,包括属性和同级选择器不起作用

C++ 项目相关知识命名空间

链接器错误:“ff_log2_tab”的多个定义

多个目标匹配链接器标志的隐式依赖关系

从 AfxGetAppModuleState 更改为 AfxGetStaticModuleState 会导致链接器错误:LNK1169:找到一个或多个多重定义的符号