问题:在ELF平台上动态链接的C ++程序是否总是会违反一个定义规则而产生未定义行为?
更具体::只需编写一个共享库即可公开一个功能
#include <string>
int __attribute__((visibility("default"))) combined_length(const char *s,
const char *t)
{
const std::string t1(t);
const std::string u(s + t1);
return u.length();
}
并通过GCC 7.3.0通过
进行编译$ g++ -Wall -g -fPIC -shared \
-fvisibility=hidden -fvisibility-inlines-hidden \
-o liblibrary.so library.cpp
我创建了一个二进制文件,该二进制文件为指向字符数组和字符串的指针operator+()
定义了一个弱符号:
$ readelf -sW liblibrary.so | grep "_ZStpl"
24: 0000000000000ee2 202 FUNC WEAK DEFAULT 12 _ZStplIcSt11char_traitsIcESaIcEENSt7__cxx1112basic_stringIT_T0_T1_EEPKS5_RKS8_
...
但是看看我得到的标准库二进制文件
$ readelf -sW /usr/lib/x86_64-linux-gnu/libstdc++.so.6 | grep "_ZStplIcSt11char_traitsIcESaIcEENSt7__cxx1112basic_stringIT_T0_T1_EEPKS5_RKS8_"
2829: 000000000012b1c0 169 FUNC WEAK DEFAULT 13 _ZStplIcSt11char_traitsIcESaIcEENSt7__cxx1112basic_stringIT_T0_T1_EEPKS5_RKS8_@@GLIBCXX_3.4.21
这就是我说的重点:我的天哪,我库中的符号也应该附加一个版本!
在当前状态下,我很好,因为我可以假定标准库二进制文件是使用与我的库相同的标头构建的。但是,如果libstdc ++-v3的实现者决定定义此函数的新版本并用GLIBCXX_3.4.22
进行标记,会发生什么情况?由于该符号较弱,因此运行时链接程序可以自由决定是采用我库的未版本化符号还是libstdc ++-v3的版本化符号。如果我将图书馆运送到这样的系统,则会在该处引发未定义的行为。一些符号版本应该为我解决了。