C语言可移植性


10

如何准确确定像C这样的语言的可移植性?我了解到编译器是特定于ISA的。如果是这样,那么C如何移植?还是仅仅是用C编写的源代码是可移植的,而不是可执行文件?特定于x86示例应用程序的可执行ISA是否与Apple的应用程序分开(假设Apple使用Motorola / PowerPC微处理器)?

Answers:


27

仅仅是用C编写的源代码是可移植的,而不是可执行文件?

正确。有人称它写一次,到处编译。

http://en.wikipedia.org/wiki/Write_once,_compile_anywhere

另一种选择是一次写入,到处运行。Java是一个很好的例子。

http://en.wikipedia.org/wiki/Write_once,_run_anywhere

即使可以实现部分跨平台可移植性,也永远不要指望代码无需修改即可在任何地方运行。


没有大量的额外语言说明,C源代码无法移植到不同的编译器或ISA或OS。简单的事情(例如标准类型的大小和对齐方式)不是C语言中的标准,因此要与其他实例交换数据的移植软件可能会非常具有挑战性。请参阅GNU Autoconf / Automake,以获取C程序员为了获得可移植性而跳过的篮球(可能是混淆的)示例。
蒂姆·威利斯克罗夫特

3
@TimWilliscroft:可移植性问题通常是由非标准库和不良的编程习惯引起的;并非由C或其标准库引起。一个简单的例子就是使用非标准的GCC扩展名或无法正确地对IO数据进行序列化/反序列化。
布伦丹

6

这不仅是特定于ISA的。例如,您问:

x86的应用程序与Apple的应用程序分开吗?

是的,即使苹果使用x86硬件,也可以。C二进制文件特定于体系结构操作系统。


1
@ Steven314:您的评论是切线。它与硬件是否标准无关,与OS X具有不同于Linux(通常为ELF)的二进制格式(Mach-O)有关。
mipadi

@Steve:EFI与BIOS仅对引导和OS内部有影响;硬件架构相同,即CPU指令集相同,因为它是相同的CPU。
vartec

删除评论,主要是因为我本来不应该将mac东西包括在内。我提到的ABI(应用程序二进制接口)和调用约定可能仍然有意义(第三项要添加到“体系结构和操作系统”中)。它们与硬件无关,除了ABI倾向于为特定的体系结构(例如,可用的寄存器)设计外,但它们与二进制可移植性有关。这不是文件格式问题-ELF在Windows和Linux上使用(由gcc使用),但是您可能无法将目标文件从一个文件移到另一个文件。
Steve314 2011年

@vartec您说过C二进制文件也是特定于操作系统的,是否因为O / S本身是ISA特定的,因此C二进制文件间接成为了O / S特定的?
KawaiKx 2011年

@Saurabh-所有本机可执行文件都特定于操作系统,因为操作系统指定了文件格式。另外,C标准库必须通过调用操作系统来实现许多功能,因此,即使文件格式标准化了,代码本身也无法在其他OS上运行。这是编译为本机代码的语言的标准,而不是诸如JVM(Java虚拟机)之类的某些虚拟机代码。可以为虚拟机编译C,但是我从来没有做过。LLVM最接近,但旨在用作编译器后端-而不是在任何地方都可以一次运行的编译环境。
Steve314 2011年

5

仅仅是用C编写的源代码是可移植的,而不是可执行文件?

究竟。您需要在每个平台上重新编译C程序。C编译器生成的机器代码在具有相同处理器/内存体系结构的机器和OS之间的可移植性非常有限。这就是为什么您会看到多平台应用程序(例如浏览器)的不同二进制分发版本的原因,例如“ Linux 64位Intel”或“ Mac OS X 32位PowerPC”(好的,最后一个只是一个例子,我知道Apple已将几年前到英特尔:-)。


3

大多数问题已得到解答,但我想补充一点,那就是耐用性是您可能要考虑的另一件事。

例如,JAVA可以编写一次,并且可以在VM所在的任何平台上运行(今天称为“运行时环境”)。但另一个优点是,您可以在2011年的计算机上运行1995年以来的Java 1.1代码。如果您的代码是在i386上编译的,而您尝试在AMD64体系结构上运行它,那是不可能的。

您还将获得虚拟机本身的改进。

然后,我要说的是,通常,从可移植性最低的语言到可移植性更高的语言:汇编器,低级编译语言(例如C),C ++,解释型语言或在虚拟机中运行的语言。

我并不是Java的捍卫者,至少不是语言或社区方面的捍卫者,但是如果您正在寻找可移植性以及与C相比性能损失最小的方法,那么这就是我要走的路。


3

关于一次写入的好答案可在任何地方编译。

人们喜欢将C视为一种可移植的语言,因为C的流行以及C编译器可用于将来的目标平台的可能性很大。另一个因素是标准库,它以平台无关的方式帮助完成常见的编程任务。

所以我想说语言的可移植性取决于:

  1. 标准化水平。
  2. 适用于不同平台/体系结构的编译器的可用性。
  3. 便携式库的深度和广度。

实际上,由于硬件或操作系统的依赖性,几乎所有复杂的C应用程序都需要一些工作才能转移到新平台。该过程称为移植。


3

“可移植性”具有多种含义。对于C而言,其含义如下:

  • 编译器已经为各种硬件和操作系统平台的C实现了编译器,这在20世纪70年代初是一个大问题。

  • 语言本身有一个公认的标准,而不是每个编译器实现都认可该语言的变体(同样,第一次设计C时,这很重要,因为Pascal和BASIC等语言有多种变体)没有得到普遍认可的东西);

  • 由于该标准,在不同平台上编译时,一致的代码将产生相同的行为。

源代码是便携式的,但是一个新的二进制具有用于每个目标产生。

但是请注意,C源极难“轻而易举”地移植。大多数应用程序要求您使用特定平台特有的扩展名,超越语言标准定义的范围,因此实际上源代码不是100%可移植的。

但是请注意,C的确在很大程度上取决于实现。各种数据类型的确切大小,溢出行为等,都取决于实现方式;该标准提供了实现必须符合的最低要求,但是实现可以自由地超出那些限制。


0

无论ISA是什么,C都不是ISA特有的。我认为您不是指PC扩展卡现在已过时的插槽。

有用于许多平台的符合标准的C编译器,并且只要您在源代码中使用完全由标准定义的语言功能,就应该能够在针对任何平台的任何C编译器上对其进行编译。

但是,一个陷阱是C标准将许多功能行为保留为实现定义或未定义的行为。这样做是为了使C语言更普遍地用于低级编程,避免了某些精确定义的行为与某些平台上的硬件支持不匹配的情况。但是,这确实使编写可移植程序变得更加困难。

而且,与某些语言不同,C没有提供Java或C#提供的那种巨大的库。您可以得到非常轻便的库来执行几乎所有事情,但是您必须做一些工作来构建它们并使它们一起工作。

C确实有一个标准库,但是与Java,C#,Python等相比,它的范围相对有限。


4
ISA =指令集架构,也称为硬件架构
vartec,
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.