C平台(H/W + S/W)是依赖还是独立

rah*_*bsb -5 c gcc

如果使用所有平台通用的所有标准C库编写C程序,无论是Unix(任何风格)还是Windows(即stdio.h,math.h等),并使用标准编译器进行编译(即GCC)并在同一个CPU拱门中的任何一个上运行它,为什么二进制文件不会在匹配所有上述标准的不同机器上运行?

当我在X86 Mac上编译C程序时,只使用标准库,为什么不能在同一CPU架构下在Linux或Windows下运行该编译二进制文件?

是因为在C运行时期间发生了特定于平台的库链接还是什么?

mah*_*mah 5

可执行二进制文件不仅仅是源代码和所需库的机器语言的组合,而是跳过现在的答案仍然是否定的:您链接的库特定于它们将要运行的系统.例如,你质疑mac vs linux ...每个系统都有自己的方式来调用陷阱进入系统(例如I/O),如果你的可执行文件有链接到它的那些项目(而不是通过共享)对象),你从一开始就注定要失败.

回到"特定于系统"...不仅像系统调用这样的问题,而且有多个可执行的二进制格式,这将导致你在很多时候不仅仅是轻微的痛苦.例如,OS X使用"Mach-O"二进制格式,而Linux使用"ELF"格式.当然,在这些文件中,您可以找到相同可执行文件的相似代码,但是您会发现该数据的不同二进制布局使得在一个系统上看起来很直接,而另一个系统上完全未知.许多例子中的一个...... Mach-O格式在可执行文件中嵌入了动态加载的库所在的位置 - 例如,相对于加载可执行文件的绝对位置或位置.这个概念(据我所知)不是ELF或Windows"PE"格式.


rub*_*nvb 5

忽略问题第10行下面的文本墙,为什么二进制文件不是OS独立的一些基本原因:

  • 每个操作系统都有一个可执行加载程序,可以执行某些操作,如加载依赖库,设置堆栈指针等...
  • 即使CPU架构是相同的,OS架构也不是,并且一些C库函数是内联实现的,从而导致特定OS的实现被编译到您的可执行文件中.
  • 函数调用可能会有不同的工作方式(例如Windows vs Linux).

所有这些都是ABI(应用程序二进制接口)的一部分,它由操作系统定义(如果由于例如专利问题,操作系统实现是不可能的,有时是编译器).

我能想到的最后一个原因:

  • C运行时是不同的; 标准留下了很多东西实现定义,这意味着许多C库在这些方面有所不同.从理论上讲,可以为所有操作系统架构实现可移植的libc,但由于操作系统界面中隐藏的细节(在Windows或Mac的情况下)或结构差异(Linux与BSD),这通常是不可能的,这最终导致不同的实现.