$ nm --demangle /usr/bin/../lib/gcc/x86_64-linux-gnu/4.9/libsupc++.a | grep "__cxxabiv1::__class_type_info::~__class_type_info"
Run Code Online (Sandbox Code Playgroud)
给出以下输出:
0000000000000000 T __cxxabiv1::__class_type_info::~__class_type_info()
0000000000000000 T __cxxabiv1::__class_type_info::~__class_type_info()
0000000000000000 T __cxxabiv1::__class_type_info::~__class_type_info()
U __cxxabiv1::__class_type_info::~__class_type_info()
U __cxxabiv1::__class_type_info::~__class_type_info()
Run Code Online (Sandbox Code Playgroud)
那么,如何解释这个输出?
T) - 它可能是怎样的?为什么链接器生成这样的库违反ODR?什么目的?为什么他们都有相同(和奇怪)的地址(0000000000000000)?T)和undefined(U)?静态库(归档文件.a)本质上是单个文件的集合.o(加上一些索引信息,以便链接器可以找到.o它需要的文件)。其中一些未定义的符号与定义它们的对象位于不同的对象中。如果你查看完整的输出,nm这一点就会变得很清楚。(或使用该-o标志nm。)
您拥有多个定义的符号的原因是这demangle不是一对一的操作。在我的副本中libsupc++,这三个定义是:
0000000000000000 T _ZN10__cxxabiv117__class_type_infoD0Ev
0000000000000000 T _ZN10__cxxabiv117__class_type_infoD1Ev
0000000000000000 T _ZN10__cxxabiv117__class_type_infoD2Ev
Run Code Online (Sandbox Code Playgroud)
为什么有几个符号都被析构函数解构了?它们是针对不同情况的析构函数。gcc 使用用于 C++ 的 Itanium ABI,其名称修改规则如下所述。