简体   繁体   English

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

[英]Using shared libraries and mismatched compilers

What are the chances using shared libraries that are compiled using different compiler versions than your program would introduce problems?使用使用不同编译器版本编译的共享库比您的程序引入问题的机会有多大?

What if the language standard your programs use is different from their?如果您的程序使用的语言标准与它们不同怎么办?

ie Could it be a problem if I link boost libraries compiled with gcc-4.8,c++11 while compiling my code with gcc-6,c++14, for instance?即,如果我在使用 gcc-6,c++14 编译我的代码时链接使用 gcc-4.8,c++11 编译的 boost 库,这会不会是一个问题?

Short answer, close to 100% that you'll have some issues unless the library was designed with this in mind.简短的回答,接近 100% 你会遇到一些问题,除非图书馆的设计考虑到这一点。 Boost was not designed with this in mind at all, it will not work. Boost 的设计根本没有考虑到这一点,它不会起作用。

Long answer, it might work under certain very specific circumstances (not for boost though).长答案,它可能在某些非常特定的情况下起作用(尽管不是为了提升)。 There are 2 main things that come into play:有两个主要的事情可以发挥作用:

  • ABI compatibility ABI 兼容性
  • Sub-library compatibility / inlined code子库兼容性/内联代码

The ABI is the easy part. ABI 是简单的部分。 If eg compiler A mangles names differently than compiler B, it won't even link.例如,如果编译器 A 与编译器 B 的名称不同,它甚至不会链接。 Or if they have different calling conventions (eg how arguments are passed through registers/stack etc) then it might link but it will not work at all / crash in pretty obvious manners.或者,如果他们有不同的调用约定(例如,参数如何通过寄存器/堆栈等传递),那么它可能会链接,但它根本无法工作/以非常明显的方式崩溃。 Also most compilers on the same platform have the same calling conventions (or can be configured appropriately) so this shouldn't be a huge problem.此外,同一平台上的大多数编译器具有相同的调用约定(或可以进行适当配置),因此这应该不是一个大问题。

Sub-library compatibility and inlined code is trickier.子库兼容性和内联代码更棘手。 For example, let's say that you have a library that passes out an allocated object, and it's the client's job to deallocate.例如,假设您有一个传递已分配对象的库,而解除分配是客户端的工作。 If the library's allocator works differently from the one in the client, then this will cause problems (eg the library uses compiler A's new , and the main program uses compiler B's delete ).如果库的分配器的工作方式与客户端中的分配器不同,那么这将导致问题(例如,库使用编译器 A 的new ,而主程序使用编译器 B 的delete )。

Or there might be code in the headers (eg inline methods).或者头文件中可能有代码(例如内联方法)。 The two compilers might compile them differently, which will cause issues.两个编译器可能会以不同的方式编译它们,这会导致问题。

Or the library might return a std::vector .或者库可能会返回一个std::vector The implementations of compiler A's vector might differ from compiler B's vector , so that won't work either.编译器 A 的vector的实现可能与编译器 B 的vector ,因此这也不起作用。

Or there might be a struct or class passed around.或者可能有一个结构或类被传递。 The two compilers might not pack/pad them the same way, so they won't be laid out the same way in memory, and things will break.两个编译器可能不会以相同的方式打包/填充它们,因此它们在内存中的布局方式不会相同,并且事情会崩溃。

So if the library is designed with this in mind, then it might work.因此,如果库的设计考虑到了这一点,那么它可能会起作用。 Generally speaking that means that:一般来说,这意味着:

  • All calls have to be extern C to avoid name mangling.所有调用都必须是extern C以避免名称混淆。
  • No passing around of any externally defined structures (eg the STL)不传递任何外部定义的结构(例如 STL)
  • Even structs might cause issues unless the packing/padding is the same in both compilers除非两个编译器中的打包/填充相同,否则即使structs也可能导致问题
  • Everything allocated by the library must also be deallocated by the library库分配的所有内容也必须由库释放
  • No throwing of exceptions (which is sort of implied by extern C )不抛出异常(这是extern C隐含的)
  • Probably a few more that I'm forgetting right now可能还有一些我现在忘记了

If the ABI (and API) is the same, it will work fine, according to gcc.gnu.org's ABI Policy and Guidelines , "given an application compiled with a given compiler ABI and library API, it will work correctly with a Standard C++ Library created with the same constraints ."如果 ABI(和 API)相同,它将正常工作,根据 gcc.gnu.org 的ABI 政策和指南,“给定使用给定编译器 ABI 和库 API 编译的应用程序,它将与标准 C++ 一起正常工作使用相同约束创建的库。”

A shared library compiled with a different ABI could work, but there are some cases of which to be aware because they could cause major bugs which would be incredibly difficult to detect.使用不同 ABI 编译的共享库可以工作,但在某些情况下需要注意,因为它们可能导致难以检测的重大错误。

gcc-4.8 and gcc-6 have different ABIs (Application Binary Interfaces), and so could output different compiled code in very specific cases, and cause an application to break. gcc-4.8 和 gcc-6 具有不同的 ABI(应用程序二进制接口),因此在非常特定的情况下可能会输出不同的编译代码,并导致应用程序中断。

However, " the GNU C++ compiler, g++, has a compiler command-line option to switch between various different C++ ABIs. " (According to ABI Policy and Guidelines.)但是,“ GNU C++ 编译器 g++ 有一个编译器命令行选项可以在各种不同的 C++ ABI 之间切换。 ”(根据 ABI 政策和指南。)

You can read more details about specific ABI issues from gcc.gnu.org :您可以从gcc.gnu.org阅读有关特定 ABI 问题的更多详细信息:

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM