C++ 为什么可以';t对象(.obj)文件是否可以跨平台移动?

C++ 为什么可以';t对象(.obj)文件是否可以跨平台移动?,c++,c,C++,C,为什么我们不能跨操作系统平台从c编译中移动.obj文件,并最终使用它来构建可执行文件 如果我们能做到这一点,我们能称C为与平台无关的语言吗?C语言是与平台无关的 编译器生成的文件(对象和可执行文件)依赖于平台。这是因为编译器的最终目标是仅为目标体系结构生成可执行文件,而不是为所有已知体系结构生成可执行文件 Java类文件是独立于平台的,因为Sun是Java的唯一设计者,它实际上制定了所有规则(从字节码到文件格式和VM行为),其他人都必须适应 本机二进制格式不会出现这种情况,每个操作系统都有自己的

为什么我们不能跨操作系统平台从c编译中移动.obj文件,并最终使用它来构建可执行文件

如果我们能做到这一点,我们能称C为与平台无关的语言吗?

C语言是与平台无关的

编译器生成的文件(对象和可执行文件)依赖于平台。这是因为编译器的最终目标是仅为目标体系结构生成可执行文件,而不是为所有已知体系结构生成可执行文件

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


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

任何规范中都绝对没有说明这是不可能的。(注意C语言和C++语言都是平台无关的,但是C和C++生成的对象文件是非平台无关的)

但是,由于C和C++都是为性能而设计的语言,大多数编译器都为目标系统生成机器代码。然后你可能会说“但是我的Linux机器和我的Windows机器运行在同一个处理器上”,但当然,这不是不同操作系统架构上的目标文件或可执行文件之间的唯一区别。虽然可以将包含同一处理器机器代码的对象文件从一种格式转换为另一种格式,但它充满了问题,例如“如何处理内联系统调用”(换句话说,有人通过

std::chrono
接口调用了
gettimeofday
,编译器内联了这个调用,这是对操作系统的直接调用-嗯,Windows不知道什么是
gettimeofday
,它被称为
GetSystemTime
或类似的,调用操作系统的方法是完全不同的…)

如果您想要一个独立于操作系统的系统,那么所有的对象文件都必须是“纯”的——当然,两个系统都需要支持相同的对象文件格式(或者支持它们的转换)


<> P>可以做一个C或C++编译器,它可以做java(和C等)的事情,编译器不为目标系统生成机器代码,而是产生一个“中间形式”。但这与C和C++的思想有点反常,那就是语言设计得非常高效,而且没有很多开销。如果可移植性比性能更重要,也许你想使用java或其他其他可移植语言…< /p> < p>不同的平台使用不同的对象文件格式。(ELF用于Linux,COFF/PE用于Windows),因此在一个平台上构建的对象文件可能无法在另一个平台上使用


请记住,对象文件(通常)是本机代码,而不是可执行形式。

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

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

在体系结构级别,可以生成像LLVM这样的中间目标代码,并在目标机器上执行JIT,以便代码适合目标体系结构

但是,除非您进行独立开发,否则平台依赖性可能会妨碍您直接运行代码。这些依赖性可能包括链接参数、标准库的实现差异、特定于平台的功能等


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

C++和C是平台独立的,因为您可以在任何地方编译相同的源代码。编译的二进制文件不是平台独立的(与Java及其JVM不同).Java是平台独立的,因为JVM,C是本机代码,Java是托管代码(用microsoft术语).Java代码不是独立于平台的,因为它只在一个平台上运行——JVM。区别在于其他人已经为目标平台编译了JVM。如果你让别人为另一个平台编译你的可移植C代码,它也会在那里运行。那么,为什么在获得可执行文件后,.obj文件没有被删除呢即使在获得可执行文件后,它也会留下来。@ EXT是因为编译成本资源和时间。java编译相对容易,C++不。保持临时文件加速构建过程很多。您可以有信心地做,以便理解为什么对象文件不被删除。