gpt4 book ai didi

c - 链接来自不同 C 编译器的目标文件

转载 作者:行者123 更新时间:2023-12-05 03:10:45 25 4
gpt4 key购买 nike

假设我有两个编译器,或者甚至是一个具有两个不同选项集的编译器。每个编译器将一些 C 代码编译成一个对象,我尝试使用一个公共(public)链接器链接这两个 .o 文件。这会成功吗?

我最初的想法是:并非总是如此。如果编译器使用相同的目标文件格式并具有兼容的选项,那么它将成功。但是,如果编译器的选项存在冲突,或者(这是一个简单的编译器)使用两种不同的目标文件格式,它将无法正常工作。

有没有人对此有更深入的了解?目标文件需要遵守哪些标准才能确信这会起作用?

最佳答案

大多数风格的 *nix 操作系统都有很好的定义和开放 ABI并且大多使用 ELF 目标文件格式,因此对于 *nix 来说完全不是问题。

Windows 的定义不太严格,不同的编译器在某些调用约定方面可能会有所不同(例如,某些编译器可能不支持 __fastcall 或可能具有不同的行为,请参阅 https://en.wikipedia.org/wiki/X86_calling_conventions )。但是主要的调用约定集(__stdcall、_cdecl 等)足够标准,可以确保成功调用一个编译器从另一个编译器编译的函数,否则程序根本无法运行,因为与 Linux 不同,Windows 中的每个系统调用都被包装通过您需要成功调用的 DLL 中的函数。

另一个问题是目标文件没有标准的通用格式。尽管大多数工具(MS、Intel、GCC (MinGW)、Clang)使用 COFF 格式,但有些工具可能使用 OMF (Watcom) 或 ELF (TinyC)。

另一个问题是所谓的“名称修改”。虽然引入它是为了支持重载同名的 C++ 函数,但 C 编译器采用它来防止使用不同调用约定定义的函数链接。例如,函数 int _cdecl fun(void);将获得编译名称 _fun 而 int __stdcall fun(void);将获得名称 _fun@0。有关名称修改的更多信息,请参见此处:https://en.wikipedia.org/wiki/Name_mangling .

最后,某些编译器的默认行为可能不同,所以是的,选项可能会阻止成功链接由不同编译器甚至同一编译器生成的目标文件。例如,TinyC 使用默认约定 _cdecl,而 CLang 使用 __stdcall。具有默认选项的 TinyC 可能不会生成可能与其他链接的代码,因为它不会在名称前加上下划线符号。为了使其可交叉链接,它需要 -fleading-underscore 选项。

但请记住上面所说的代码可能会成功混合。例如,我成功地将 Visual Studio、Intel Parallel Studio、GCC (MinGW)、Clang、TinyC、NASM 生成的代码链接在一起。

关于c - 链接来自不同 C 编译器的目标文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38902314/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com