在使用C/C++编程时,迟早会遇到"未定义的引用错误"。这通常是由于缺少库文件导致的,大多数情况下只需要链接上缺失的库文件即可在几秒钟内解决这些错误。
然而,当我们使用模板并将声明和实现分别放在不同的文件中时,可能会出现由于"意外"的模板实例化而导致的未定义引用错误。不幸的是,我们现在得到的所有信息都只是一个"未定义的引用错误"实例,没有任何可能提示错误原因的线索,例如调用者的行号等。
我想知道的是:是否有一种简单的方法来找出调用函数/模板并导致未定义引用错误的实际源代码行?
如我在回答这个问题时所提到的,能否直接获取导致链接错误的行数取决于编译器是否发出了所有必要的信息。
首先,以下是我遇到过的导致您看到的行为的情况:
如果您遇到类似于以下链接错误,我建议您跟踪一下:
asdf.o: In function `whatever':
asdf.o(.text+0x1238): undefined reference to `fdsa'
...因为至少你有一个地址可以使用。
首先尝试使用addr2line
:
~ addr2line -e asdf.o 0x1238
# If it works, you'll get:
asdf.cc:N
# If it doesn't work, you'll get:
??:?
objdump
:~ objdump --dwarf=decodedline asdf.o
asdf.o: file format elf64-x86-64
Decoded dump of debug contents of section .debug_line:
CU: asdf.cc:
File name Line number Starting address
asdf.cc 1 0x1234
asdf.cc 3 0x1254
asdf.cc 5 0x1274
.debug_line
中没有与链接错误中的 0x1238
(地址)对应的条目,因此可能是编译器魔法(例如由类似于堆栈保护程序或消毒剂之类的东西添加的额外代码),或者希望它与第 1/3 行发生的任何事情有关,因为该地址位于这两行之间。
grep -n
来获取行号... 但是如果你有400个名为size()
的函数,那可能帮助不大... - Mats Peterssongrep
命令查找未定义的标识符。 - Captain Obvlious