用不同的编译器创建的(C)目标文件是否与二进制兼容?


11

我了解C ++编译器彼此不兼容。但是,我无法在C上找到关于此主题的任何东西。我知道C标准为编译器提供了很多空间,使它们能够执行合适的事情,例如,他们认为合适:例如,大多数(所有?)数据类型的大小和对齐方式是实现定义的,除了一些最小的保证。因此,两个编译器(或同一编译器的两个版本)可能在许多细节上存在分歧。

我是否认为不能保证使用不同编译器编译的两个目标文件实际上可以正确链接是正确的吗?例如,一个目标文件中指针的大小可以是32位,而在另一个目标文件中则可以是64位。但是如果是这样,为什么C库有时会以预编译形式分发?是否期望我将使用与他们相同的编译器(例如gcc),或者使用某些事实上的标准来确保二进制兼容性?带有外语接口的其他语言如何确保在与C对象文件链接时事物能够正确对齐?


据我所记得,只要C对象文件是为同一平台编译的,它们就应该相互兼容。目标文件只是一个包含可加载二进制代码的归档文件,带有一些符号表,可用于访问模块内的每个符号。
Giorgio 2014年

2
可以使libs兼容,我不认为obj一定是兼容的
棘手的怪胎

@Giorgo“同一平台”是指CPU体系结构还是CPU体系结构+ OS?
2014年

@ratchetfreak我给人的印象是,lib在大多数情况下只是多个目标文件的串联。错了吗
2014年

我不希望对象在不同的​​编译器之间兼容。
old_timer 2014年

Answers:


10

普遍的答案是不,C语言编译器彼此不兼容。C语言标准没有定义任何类型的二进制互操作性,并且大多数编译器作者甚至都没有尝试。

我需要证明这一点。C编译器发出的对象必须与运行时库链接,以生成可执行文件或运行时可链接库。尽管C运行时库提供的可见函数应该兼容,但是也将有不可见函数,它们对于实现是唯一的,并且会阻止互操作性。

缺乏兼容性还扩展到同一编译器的不同版本。通常,用较旧和较新版本的编译器编译的程序和库不能链接在一起,而用MSVC编译的程序和库不能与GCC编译的程序和库链接。

有一个特定且非常有用的例外。每个平台都提供了动态链接ABI(应用程序二进制接口),并且可以使用兼容该ABI的任何语言的任何程序。因此,通常可以使用MSVC(或其他方式)构建DLL(在Windows上)并从由其他版本的MSVC或GCC编译的程序中调用它,反之亦然。

Windows上还有另外两个ABI:COM和.NET程序集,它们涵盖了多种语言。因此,互操作性绝对是可能的,但兼容却不是。


通过比较接头图可以很容易看出不相容的程度。对于GNU使用ld -M,对于MSVC使用link /map。研究两个生成的文件。这两个名称中都有您可以识别的名称,例如printf和main,尽管(取决于选项)名称可能会以各种方式被破坏。它们还将具有完全不同的名称,其中许多您将无法识别。为了使不同编译器生成的目标文件兼容,它们必须在所有这些名称上达成共识,而从不这样做。甚至同一编译器的不同版本也无法始终做到这一点。


这个答案似乎与巴特的矛盾。听起来只有共享库兼容。您能解释一下为什么C运行时库的不可见,特定于实现的功能会阻止互操作性吗?您还说“ C编译器发出的对象必须与运行时库链接才能生成可执行文件或运行时可链接库”-静态库呢?
2014年

正如Bart所说,只有具有ABI的库才兼容。共享库(在Unix上)是ABI的一种,还有其他。编写HelloWorld.c,使用MSVC和gcc进行编译,比较地图,您将看到它们之间的差异。“运行时库”是指在每个C / C ++编译中自动引用的基本支持功能,这些功能可以静态或动态链接。阅读地图或CRT源代码以查看它们。
david.pfx 2014年

我不知道比较这些映射的含义是什么,所以我会更具体一点:在实践中可以安全地假定给定CPU架构和OS组合的所有编译器都兼容吗?例如,我有main.c(我用gcc编译)和mylibrary.c(我用clang编译),都针对Linux x64。假设一个相当主流的操作系统(Linux,Mac,Windows),是否可以安全地假定不管两个编译器是什么,它都可以工作?
2014年

1
不太可能检查clang链接图。参见编辑。
david.pfx 2014年

17

您在寻找什么,称为ABI(应用程序二进制接口)。

C语言没有定义ABI,因此从这个意义上说,实际上并不能保证使用不同编译器编译的C文件将相互配合。

另一方面,在大多数平台上,OS都定义了与其进行接口的ABI,并且所有针对该OS和处理器系列的编译器也使用相同的ABI与非OS组件进行接口。因此,实际上,由不同的编译器创建的C对象可以相互配合。


那讲得通。我认为共享库也遵循操作系统的ABI吗?
2014年

3
@Doval 特别是共享库,它们需要被外界调用。
toasted_flakes 2014年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.