问题描述
由于所有函数名都被修饰,我不得不修复在链接时发生的C ++错误(尤其是未定义的参考错误),这让我感到非常沮丧。名称错误的示例:
_ZNK5boost7archive6detail11oserializerINS0_13text_oarchiveEN9galandria8UniverseEE16save_object_dataERNS1_14basic_oarchiveEPKv
很难阅读,找到实际功能更加困难。
解决方法
ld
(GNU链接器)能够取消C ++函数名称的修饰。 ld
文档从其man
页面撤消:(在线here可用)
--demangle[=style]
--no-demangle
These options control whether to demangle symbol names in error
messages and other output. When the linker is told to demangle,it tries to present symbol names in a readable fashion: it strips
leading underscores if they are used by the object file format,and converts C++ mangled symbol names into user readable names.
Different compilers have different mangling styles. The optional
demangling style argument can be used to choose an appropriate
demangling style for your compiler. The linker will demangle by
default unless the environment variable COLLECT_NO_DEMANGLE is
set. These options may be used to override the default.
让我们看一个例子:
void foo();
void foo(int);
int main() {
foo();
foo(5);
}
这是一个简单的有效代码。这将编译但无法成功链接,因为此处没有实现foo()
和foo(int)
。现在,我们将使用以下命令对其进行编译:
g++ main.cpp -c -o main.o
它将成功编译。现在,让我们尝试使用以下命令将其与禁用拆解链接起来:
g++ main.o -Wl,--no-demangle
它应该显示链接错误,并带有一些奇怪的名称,如下所示:
main.o: In function `main':
main.cpp:(.text+0x5): undefined reference to `_Z3foov'
main.cpp:(.text+0xf): undefined reference to `_Z3fooi'
collect2: error: ld returned 1 exit status
现在,让我们尝试使用以下命令与启用的拆解链接:
g++ main.o -Wl,--demangle
使用以下参数将函数名称拆散会出现错误:
main.o: In function `main':
main.cpp:(.text+0x5): undefined reference to `foo()'
main.cpp:(.text+0xf): undefined reference to `foo(int)'
collect2: error: ld returned 1 exit status
这里-Wl
表示链接器的参数。
据我所知,g++
会自动取消合并。
我通过两种方式处理这些问题:
-
c++filt
命令可消除事物混乱。 -
有时使用clang而不是gcc进行编译,反之亦然,可以深入了解编译问题。
不幸的是,我不确定是否有可能直接从链接器获取拆散的输出:-(