假设我们有一个接受或返回某种标准类的共享库:
//lib.h
#include <vector>
std::vector<int> returnSomeInts();
//lib.cpp
#include "lib.cpp"
std::vector<int> returnSomeInts() {
return {1, 3, 5};
}
很明显,在编译共享库 lib.so
时,必须针对标准库的特定版本编译此代码,例如 -std=c++11。
现在假设我们有一个应用程序将使用我们的共享库,但它将针对较新的标准库进行编译,例如 -std=c++2a
//app.cpp
#include <lib.h>
int main()
auto v = returnSomeInts();
//Process v
}
由于标准库定义了内联类,如果类成员的布局发生变化,ABI 兼容性就会被破坏,因此上面的代码将无法正常工作。
我的问题是:当使用不同的 C++ 标准针对相同的 header 进行编译时,std 库的通用实现是否可以保证 ABI 的稳定性?当针对不同的头文件版本(例如 libstdc++-8 和 libstdc++-9)进行编译时?
PD:上面的代码只是一个例子,我并不是特指std::vector
最佳答案
实践中的 ABI 没有链接到标准,例如考虑以下代码 compiled使用 gcc 4.9.4 和 gcc 5.1 使用相同的标志:
-std=c++11 -O2
#include <string>
int main(){
return sizeof (std::string);
}
gcc 4.9.4 从 main 返回 8,gcc 5.1 返回 32。
至于保证:它很复杂:
标准不保证任何内容。
实际上 MSVC 曾经破坏 ABI 兼容性,他们停止了(v140、v141、v142 使用相同的 ABI),clang/gcc 有很长一段时间稳定的 ABI。
对于那些有兴趣了解更多信息的人: 有关与此问题没有直接关系的 ABI/C++ 标准的广泛讨论,请查看此 blog邮政。
关于linux - 标准库 ABI 兼容性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60836246/