混合 libstdc++ 版本

Mixing libstdc++ versions

有 2 个软件团队为同一个 OS(科学 Linux 6.5)开发 C++ 应用程序:

Team_A 使用 OS 提供的编译器和库(GCC 4.4.7、GLIBC_2.12、GLIBCXX_3 .4.13),构建其 C++98 应用程序和各种共享库。

Team_B 使用从源代码构建的较新 GCC 版本 (4.8.3)。它是一个本地编译器,它链接到 OS libc,并使用 OS 标准头文件,但有自己的 stdc++ 版本 (GLIBCXX_3.4.19)。 Team_B 在 C++11 模式下使用此编译器构建其应用程序 (AppB),并随它一起部署 libstdc++ 和 libgcc_s。

Team_A 以共享库(.so、.hpp)的形式向 Team_B 提供服务:LibA。库的API是一组C++类(在header中声明,.so中实现),methods以std::string等stdc++类为参数。

此时我们遇到了问题:AppB 构造 GLIBCXX_3.4.19 C++11 风格的 std::whatever 对象并将它们传递给 LibA,后者将它们解释为 GLIBCXX_3.4.13 C++98 样式对象,这可能不向前兼容。

这是个问题吗?它会导致应用程序崩溃吗? std::whatever 实现是否在版本之间兼容(相同的内存布局)? C++98 与 C++11 相比如何?

一些让我比较迷惑的情节曲折:

我想了解在这种情况下到底发生了什么,是否存在风险和无效问题。让团队处于相同的开发环境中不是一种选择。从 API 中删除 std:: 类 也很难做到。

欢迎指点! :)

与 C 不同,C++ 没有定义的 ABI。这意味着....

  1. C++ 重整可能会改变 wikipedia : name mangling。请注意 Alpha 名称修改是如何更改的。
  2. class 的结构可能不同。布局结构的 protected:private:public: 部分可能会有不同的决定。 vtable 的位置和含义可以在编译器之间移动。不同的编译器版本之间可能存在不同的预定义函数,例如 vtable 中的 typeinfo。
  3. STL 中结构的实现可能因 C++ 版本而异(例如,字符串共享在早期的 Visual studio 实现中完成,但在 C++11 中已被禁止)。
  4. 在Windows中,不同的运行时可能会以不同的方式管理它们的内存(绑定到不同的malloc/free)。传递完整的对象或指针时,这可能会导致调用不正确的自由实现。

你能做些什么来缓解这些问题?

资源分享

不提供编译库,而是将服务作为源代码交付,以便在同一环境中编译。

标准化 libstdc++

源编译器,可以用旧的 stdC++ 重新编译。这将限制第 3) 点的影响。

创建外观

两个团队之间有一个接口,需要说共同语言。这个语言应该是C.

团队 A => C++ facade/stub => C 接口 => C++ facade/proxy => 团队 B.

立面应建在将要使用的环境中。