为什么对象 (.obj) 文件不能跨平台移动?
Why can't object (.obj) files be moved across platforms?
为什么我们不能将。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),您确实可以直接运行为其他平台编译的代码。
- C++我的数学有什么问题,为什么我的代码不能正确循环
- 为什么在没有显式默认构造函数的情况下,将另一个结构封装在联合中作为成员的结构不能编译
- 为什么我的for循环不能正确获取argv
- 不能在初始值设定项列表中将非常量表达式从类型 'int' 缩小到'unsigned long long'
- 为什么我不能在 FOR LOOP 中使用 i/10,C++?
- 为什么我不能在不创建字符串变量的情况下使用函数的字符串输出
- 为什么模板类中的对象不能返回值
- 为什么我不能在一个类的不同行中声明和定义成员变量?
- 为什么我不能在 C++ 中的特定函数重载中调用同一函数的任何其他重载?
- ld:bind_at_load和-bitcode_bundle(Xcode设置ENABLE_bitcode=YES)不能
- 数组长度,为什么从命令行获取时不能使用它?
- Windows/Cygwin - 不能使用 pybind11 - 犯错误
- 为什么我不能使用 EGL 创建无头 OpenGl 上下文?
- 递归模板化函数不能分配给具有常量限定类型"const tt &"的变量"state"
- 为什么我不能将一个对象push_back到属于另一个类的对象向量中?
- 为什么我不能将 rand() 与数组的大小一起使用?
- 为什么虚函数不能是静态的和全局的?
- 为什么我不能在 while 循环中创建线程?
- 为什么这个音频包络不能通过开关的情况?
- 为什么对象 (.obj) 文件不能跨平台移动?