使用共享库和不匹配的编译器

时间:2017-01-13 19:06:20

标签: c++ shared-libraries

使用与您的程序引入问题不同的编译器版本编译的共享库的可能性有多大?

如果您的程序使用的语言标准与其不同,该怎么办?

例如,如果我在用gcc-6,c ++ 14编译代码时用gcc-4.8,c ++ 11编译的boost库是否会出现问题?

2 个答案:

答案 0 :(得分:1)

简短的回答,接近100%你会遇到一些问题,除非图书馆的设计考虑到这一点。 Boost根本没有考虑到这一点,它不起作用。

答案很长,它可能在某些非常具体的情况下起作用(尽管不是为了提升)。有两个主要的事情发挥作用:

  • ABI兼容性
  • 子库兼容性/内联代码

ABI很容易。如果是编译器的名称与编译器B不同,它甚至不会链接。或者,如果它们具有不同的调用约定(例如,如何通过寄存器/堆栈等传递参数),那么它可能会链接但它将无法正常工作/以非常明显的方式崩溃。此外,同一平台上的大多数编译器都具有相同的调用约定(或者可以进行适当配置),因此这不应该是一个大问题。

子库兼容性和内联代码比较棘手。例如,假设您有一个传递已分配对象的库,并且客户端的工作是取消分配。如果库的分配器与客户端的分配器的工作方式不同,那么这将导致问题(例如,库使用编译器A的new,主程序使用编译器B的delete)。

或者标题中可能有代码(例如内联方法)。这两个编译器可能会以不同的方式编译它们,这会导致问题。

或者图书馆可能会返回std::vector。编译器A的vector的实现可能与编译器B的vector不同,因此也不会有效。

或者可能存在传递的结构或类。这两个编译器可能不会以相同的方式打包/填充它们,因此它们不会以相同的方式在内存中布局,并且事情会中断。

因此,如果图书馆的设计考虑到这一点,那么它可能会起作用。一般来说,这意味着:

  • 所有来电都必须extern C以避免名称损失。
  • 没有绕过任何外部定义的结构(例如STL)
  • 偶数structs可能会导致问题,除非两个编译器中的打包/填充相同
  • 图书馆分配的所有内容也必须由图书馆
  • 取消分配
  • 不抛出异常(extern C暗示的那种)
  • 可能还有一些我现在忘记了

答案 1 :(得分:1)

如果ABI(和API)相同,它将正常工作,根据gcc.gnu.org' s ABI Policy and Guidelines,"给定使用给定编译的应用程序编译器ABI和库API,它将与使用相同约束创建的标准C ++库一起正常工作 。"

使用不同的ABI 编译的共享库可以工作,但是有一些情况需要注意,因为它们可能至少会出现主要错误,这将非常难以检测。< / p>

gcc-4.8和gcc-6具有不同的ABI(应用程序二进制接口),因此可以在非常特定的情况下输出不同的代码,并导致应用程序中断。

然而,&#34; GNU C ++编译器g ++有一个编译器命令行选项,可以在各种不同的C ++ ABI之间切换。&#34; (根据ABI政策和指南。)

您可以从gcc.gnu.org了解有关特定ABI问题的更多详细信息: