是什么阻止了C的编译/解释/ JIT处理?


9

Java经常以其惊人的可移植性而受到赞誉,我认为这是因为JVM。我的问题是阻止C进行编译/解释/ JIT的原因是什么,如果是这样,C也可以编写一次并使其在您拥有的任何设备上工作。但这不是处理C程序的流行机制。

用这种方式处理C的缺点是什么,当然除了可移植性以外,用这种方式处理Java而不编译为机器代码的优点是什么?


您的问题在这里已经有一些很好的答案:stackoverflow.com/questions/3925947/…–
布朗

2
@delnan我的观点是,当语言可能针对具有JIT的虚拟机或vm将识别硬件中缺少的功能并重新编译的情况下,“什么阻止C被编译/解释/ JIT化”确实失去了它的含义。代码以匹配现有硬件(例如OSX上用于不同图形卡的OpenGL(用C编写))。不,您不能在一台计算机上获取针对目标llvm编译的内容并在另一台处理器上运行它。但是编译/解释/ JIT行可能会很模糊。

1
Java 因其惊人的可移植性而经常被炒作。它可移植到已编译JVM的系统上,也就是说,已为其编译JVM(用C编写)的系统。没有什么可以阻止以相同的方式处理C代码,除非没有人看到这样做有足够的好处来证明其合理性。
Pete Becker

2
我对此感到困惑:“是什么阻止了C的编译/ [...]”。嗯,什么都没有?
Andres F.

1
如今,C编译器很快,因此“ make myprog.c; myprog”的运行速度可能会比大多数解释器快。
James Anderson

Answers:


18

C是我所说的中级语言。它的目的是充当“非常高级的汇编器”,这就是为什么它可以作为编译器目标很好地工作,并且为什么它可以很好地包含可移植性。

从历史上看,在方法调用的上下文中,解释器通常与高级语言一起使用。解释器以其最简单的形式仅解析源语言中的每个关键字及其关联的标记,并将其转换为方法调用和参数。实际上,大多数解释器所做的就是将源语言转换为某种中间表示形式,而该表示形式就是被解释的。

是什么阻止了C被解释或激化? 没有。 但这不是C的存在理由。


6

首先,值得注意的是,Sun的JVM是用C编写的。当需要可移植性时,C是一种非常流行的语言。

即使没有很多C 程序,C 语言也可以移植。这是因为C对程序员没有施加太多限制,也没有做出太多假设。如果C程序员希望其程序具有可移植性,则必须对自己施加这些限制。

实际上,这确实比承受Java对您施加的限制要困难得多。主要是要注意您的字节序和原始大小,并使用GTK +等可移植库而不是平台特定的库。

您可以创建一个支持虚拟机,甚至可能支持JVM的GTK +目标和C编译器,并使现有代码可以进行很少的更改。实际上,如果没有垃圾回收,C虚拟机可能会简单得多。但是,为什么要这么做?

相反,将Java编译为本地代码也是可行的。基本上,这就是JIT的工作。但是,为什么要这么做?我敢肯定有些宠物项目“只是因为”而这样做,但是并没有被认真使用。


5

你说:

Java经常以其惊人的可移植性而受到赞誉,我认为这是因为JVM。

在第一句话中,您错了。Java由于JVM而无法移植。Java是可移植的,因为Java语言的定义方式不会给实现者留下任何程序行为的余地。

例如,Java有两种类型:“ int”(带符号的32位整数)和“ long”(带符号的64位整数)。C和C ++具有“ int”(至少16位带符号),“ long”(至少32位带符号)和“ long long”(至少64位带符号)。这是因为C应该在许多不同的处理器上运行,并允许它们表现不同。

C可以为这些类型定义固定的大小。如果有的话,那么36位处理器将无法实现C语言。而且他们确实不能实现Java!因此,C允许该语言与各种不同的计算机一起使用。不可避免的是,这将允许创建不可移植的代码。这是语言问题。


可以在36位计算机上模拟32位算术运算,并用0xFFFFFFFF将每个操作的结果截断为32位。因此,这些机器可以实现Java,这比Java允许基于nonet的类型要慢。
dan04 2015年

4

Java具有高度的可移植性,特别是因为该语言针对Java虚拟机,顾名思义,它不是真正的机器。由于您可以在许多不同类型的真实计算机的体系结构上实现虚拟机,因此基于JVM的程序具有很高的可移植性。

另一方面,C是专门为在实际硬件上运行而设计的,因为它是为实现需要完全硬件访问的操作系统的特定目的而创建的。这意味着C代码在设计上并不是特别可移植的,并且在将C程序从一个平台移植到另一个平台时,特定于目标体系结构的各个部分都需要重写到一个或另一个程度。


7
C具有高度的可移植性。您只需要在目标平台上重新编译,就可以避免那些专门有意地不可移植的代码。
罗伯特·哈维

5
@RobertHarvey:...诸如各种基本元素大小之类的基本知识?;)
Mason Wheeler 2015年

2
是的,那些东西。不幸的是,问题仍然存在,但是该语言可以通过其他方式完全移植,并且有多种方法可以确保原始大小在所有平台上都能正常工作。
罗伯特·哈维

3
@RobertHarvey:我想说C使得编写可移植程序成为可能,但并没有使它固有地容易。
布朗

2
@RobertHarvey:你想发动一场宗教战争吗?;-)我最喜欢的可移植语言是Python。
布朗

3

实际上有C的解释版本,但是它们主要是用于快速实验,而不是生产系统。

它们并不常见,因为毕竟,如果不获得小型,快速和静态的可执行文件,为什么还要承受所有C的特性?


3

从理论上讲,C和Java都可以编译为本地代码,解释或编译为虚拟机。

没有将C编译为虚拟机的技术原因是,根本就没有标准的虚拟C机。

而且似乎没有人想要定义虚拟C机,甚至不想编译为Java虚拟机(这完全有可能)。可能是因为没有人使用C来放松其无与伦比的速度。也可能是因为C在开放源代码社区中最强大,可以通过编译轻松地实现可移植性(分发和重新编译源代码并执行),因此他们认为封闭时不需要这种可移植性(分发和执行二进制文件)源开发人员。


1

实际上,这已经完成。有主要的编译器支持对LLVM的编译(我知道clang可以,并且我相信gcc也可以)。LLVM可以是JIT,就像Java代码被编译成JIT的字节码一样。

但是,与C相比,使Java成为“跨平台”的原因是Java具有一个大型的运行时库,该库已移植到许多平台上。C明确不遵循这种范例。


如果您小心地进行编码,那么带有POSIX的C可以很方便地移植到任何POSIX系统。
Basile Starynkevitch 2015年

0

Java和C之间有一些主要区别。Java是通过Java虚拟机(JVM)与操作系统隔离的。JVM将操作系统从程序中抽象出来。一个Java应用程序可能会向JVM请求一块内存,然后JVM向操作系统请求该内存。有许多用于不同平台/操作系统的JVM。JVM允许相同的Java程序在不同的平台上运行。

使用C,没有操作系统隔离。C程序(通常)直接在OS之上运行,直接进行OS调用。这将C程序与特定的操作系统/平台联系在一起。任何不平凡的程序都将调用操作系统。另外,C程序被编译为机器代码,这是特定于硬件的。x86的已编译C程序不能直接在ARM处理器上运行。


1
Java被编译成与平台无关的字节码,该字节码可以(理论上至少)由任何平台上的任何JVM执行。C会针对您要针对的任何CPU编译成汇编语言(因此,如果您要针对x86体系结构,则C编译器将创建x86汇编程序,或者如果您针对该体系结构或ARM汇编程序,则将创建amd64汇编程序)。然后,将汇编语言转换为目标文件(实际上是二进制汇编程序),然后将其链接到可执行文件中(几种不同的格式,具体取决于目标计算机)。
Craig

1
Java语言规范中没有任何关于JVM的内容,实际上,有Java的实现没有JVM。在Android上,Java程序在Dalvik VM(现已过时)或Android Runtime上运行,其中包括用于CLI的Java实现,可编译为ECMAScript的实现以及可编译为本机代码的实现。有C编译器可编译到JVM。有C编译器可编译为ECMAScript。有C口译员。
约尔格W¯¯米塔格
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.