混合libstdc++版本

Mixing libstdc++ versions

本文关键字:版本 libstdc++ 混合      更新时间:2023-10-16

有两个软件团队为同一操作系统(Scientific Linux 6.5(开发C++应用程序:

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

Team_B使用从源代码构建的较新GCC版本(4.8.3(。它是一个本机编译器,它与操作系统libc链接,并使用操作系统标准头,但有自己版本的stdc++(GLIBCCXX_3.4.19(。Team_B在C++11模式中使用此编译器来构建其应用程序(AppB(,并随它一起部署libstdc++和libgcc_s。

Team_A以共享库(.so,.hpp(的形式向Team_B提供服务:LibA。库的API是一组C++类(在头中声明,在.so中实现(,方法以std::string和其他stdc++类为参数。

在这一点上,我们得出了问题:AppB构造了GLIBCXX_3.4.19 C++11样式std::anything对象,并将它们传递给LibA,LibA将它们解释为GLIBCXX_3.4.13 C++98样式的对象,这可能是不兼容的。

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

一些让我更加困惑的情节转折:

  • AFAICT,当AppB运行时,只加载了一个libstdc++一即使LibA链接到旧版本,它也不会被加载
  • 但是libstdc++中的符号是有版本的。因此,如果LibA明确使用旧版本的符号,它将与之链接。这意味着AppB将使用同一功能的两种不同实现和伦敦银行同业拆借利率
  • std::string和containers是模板类,这意味着他们实现的一部分最终会出现在生成的地方,一部分在libstdc++.so中。即使加载了较新的libstdc++LibA中的模板代码来自旧版本

我想了解在这种情况下到底会发生什么,如果它是有风险的,并且是无效的问题。让团队处于同一个开发环境中不是一种选择。从API中删除std::类也是非常困难的。

欢迎任何指针!:(

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

  1. C++的篡改可能会改变维基百科:名称篡改。请注意Alpha名称的更改
  2. 类的结构可能不同。可能存在用于布置结构的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++facial/proxy=>团队B

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