linux - 标准库 ABI 兼容性

标签 linux gcc g++

假设我们有一个接受或返回某种标准类的共享库:

//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/

相关文章:

node.js make 失败,找不到 ld

c++ - 如何在 C++ 程序中包含同名的 C 系统头文件而不是 C++ 系统头文件?

linux - 即使 nm 指示此符号存在于共享库中,也未定义对符号的引用

c - netcat gcc 编译选项,以便 IDA pro 可以显示函数名称

无法理解关于 linux 中函数调用的简单 c 代码的输出

c++ - 解析 GCC 打印的 C/C++ 编译错误

c++ - 当我尝试使用ONE LINE编译程序时,g++崩溃

linux - 在 Linux 中使用 head 和 tail 返回文件的第 n 项

c++ - OpenCV 2.4.2 calcOpticalFlowPyrLK 没有找到任何点

python - 使用mmap找出缓存未命中