我发现必须修复链接时发生的 C++ 错误(尤其是未定义的引用错误)非常令人沮丧,因为所有函数名称都被破坏了。错误名称的示例:
_ZNK5boost7archive6detail11oserializerINS0_13text_oarchiveEN9galandria8UniverseEE16save_object_dataERNS1_14basic_oarchiveEPKv
Run Code Online (Sandbox Code Playgroud)
读起来太难了,找到真正的功能就更难了。
有没有办法说服ld输出损坏的名称?
ld(GNU 链接器)能够解析 C++ 函数名称。ld有关从其man页面进行破坏的文档:(可在此处在线获取)
--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.
Run Code Online (Sandbox Code Playgroud)
让我们看一个例子:
--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.
Run Code Online (Sandbox Code Playgroud)
这是一个简单有效的代码。这将编译但无法成功链接,因为这里没有foo()and的实现foo(int)。现在我们将使用以下命令编译它:
void foo();
void foo(int);
int main() {
foo();
foo(5);
}
Run Code Online (Sandbox Code Playgroud)
它将编译成功。现在让我们尝试使用以下命令将其与禁用的解除修饰链接起来:
g++ main.cpp -c -o main.o
Run Code Online (Sandbox Code Playgroud)
它应该显示一些奇怪的损坏名称的链接错误,如下所示:
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
Run Code Online (Sandbox Code Playgroud)
现在让我们尝试使用以下命令来链接启用的分解:
g++ main.o -Wl,--no-demangle
Run Code Online (Sandbox Code Playgroud)
我们会收到带有参数的分解函数名称的错误,如下所示:
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
Run Code Online (Sandbox Code Playgroud)
这里的-Wl意思是链接器的参数。
据我所知,g++可以自动启用解密。