为什么对象 (.obj) 文件不能跨平台移动?

Why can't object (.obj) files be moved across platforms?

本文关键字:不能 跨平台 移动 文件 对象 obj 为什么      更新时间:2023-10-16

为什么我们不能将。obj文件从c编译跨操作系统平台,并在最后使用它来构建可执行文件?

如果我们可以这样做,我们可以把C称为像Java一样的平台独立语言吗?

C语言 平台无关。

编译器生成的文件,对象文件和可执行文件,是平台相关的。这是因为编译器的最终目标是仅为目标体系结构生成可执行文件,而不是为每个已知体系结构生成可执行文件。

Java 文件是平台独立的,因为Sun是Java的唯一设计者,它实际上制定了所有的规则(从字节码到文件格式和VM行为),其他人必须适应。

本机二进制格式不会发生这种情况,每个操作系统都有自己的格式,编译器有自己的对象格式,每个CPU都有自己的ISA。

在任何规范中绝对没有说这是不可能的。(注意C和c++语言都是平台独立的,但是C和c++生成的OBJECT文件不是平台独立的)

然而,由于C和c++都是为性能而设计的语言,大多数编译器为目标系统生成机器码。然后你可能会说"但是我的Linux机器和我的Windows机器运行在同一个处理器上",但是当然,这不是目标文件或可执行文件在不同操作系统架构上的唯一区别。,而它可能会把对象文件包含机器代码相同的处理器从一种格式到另一个地方,它是充满了问题诸如"内联系统调用"(换句话说,一个叫gettimeofday通过std::chrono接口,和编译器内联调用,这是一个直接调用操作系统,Windows不知道gettimeofday是什么,它叫做GetSystemTime或一些这样的人,和方法的调用操作系统是完全不同的…)

如果你想要一个独立于操作系统的系统,那么所有的目标文件必须是"纯"的——当然,两个系统需要支持相同的目标文件格式(或支持它们的转换)。

一个C或c++编译器可以做Java(和c#等)做的事情,编译器不为目标系统生成机器码,而是生成一个"中间形式"——但这与C和c++的思想有点矛盾,C和c++的思想是语言被设计得非常高效,没有很多开销。如果可移植性比性能更重要,也许您想使用Java?或者其他可移植语言…

不同的平台使用不同的目标文件格式(Linux使用ELF, Windows使用COFF/PE),因此在一个平台上构建的目标文件可能无法在另一个平台上使用。

记住,目标文件(通常)是本机机器码,只是不是可执行的形式。

C在源代码级别是跨平台的。

一旦编译完成,二进制文件就会受到很多因素的影响。

在体系结构层面,可以生成像LLVM这样的中间目标代码,并在目标机上执行JIT,使代码适合目标体系结构。

然而,除非你做的是独立开发,否则平台依赖性会阻止你直接运行代码。这些依赖关系可能包括链接参数、标准库实现的差异、特定于平台的特性等。

仍然有例外,如果操作系统提供二进制级兼容性(如BSD),您确实可以直接运行为其他平台编译的代码。