链接器。如何同时定义和取消定义符号?
Linker. How could symbol be defined and undefined simultaneously?
$ nm --demangle /usr/bin/../lib/gcc/x86_64-linux-gnu/4.9/libsupc++.a | grep "__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()
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()
那么,如何解释这个输出?
- 这是该符号的多个定义(三个
T
)- 怎么可能?为什么链接器生成这样的库违反了ODR
?目的是什么?为什么它们都有相同(且奇怪)的地址 (0000000000000000
)?
- 同一个符号如何同时定义 (
T
) 和未定义 (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
为什么有几个符号都demangle到析构函数?他们是 destructors for different situations. gcc uses the Itanium ABI for C++, whose name mangling rules are described here.
$ nm --demangle /usr/bin/../lib/gcc/x86_64-linux-gnu/4.9/libsupc++.a | grep "__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()
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()
那么,如何解释这个输出?
- 这是该符号的多个定义(三个
T
)- 怎么可能?为什么链接器生成这样的库违反了ODR
?目的是什么?为什么它们都有相同(且奇怪)的地址 (0000000000000000
)? - 同一个符号如何同时定义 (
T
) 和未定义 (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
为什么有几个符号都demangle到析构函数?他们是 destructors for different situations. gcc uses the Itanium ABI for C++, whose name mangling rules are described here.