Cがコンパイル/解釈/ JITされるのを妨げる原因は何ですか?


9

Javaは、その驚くべき移植性でしばしば賞賛されています。これは、JVMが原因だと思います。私の質問は、Cがコンパイル/解釈/ JITされるのを阻止するものです。もしそうなら、Cは1度だけ記述して、あなたが持っているどのデバイスでも動作させることができます。しかし、これはCプログラムを処理するための一般的なメカニズムではありません。

もちろん、このようにCを処理することの欠点は何ですか?もちろん移植性以外に、このようにJavaを処理してマシンコードにコンパイルしないことの利点は何ですか?


あなたの質問はすでにここにいくつかの非常に良い答えを持っていますstackoverflow.com/questions/3925947/...
ドク・ブラウン

2
@delnan私の要点は、言語がJITを備えた仮想マシンをターゲットとする可能性がある場合、またはvmがハードウェアで欠落している機能を識別して再コンパイルする状況では、「Cのコンパイル/解釈/ JITの停止」が本当に意味を失うということです既存のハードウェアと一致するコード(異なるグラフィックスカード用のOSX上のOpenGL(Cで記述)など)。いいえ、あるマシンでllvmをターゲットとするようにコンパイルされたものを取得して、別のプロセッサでそのように実行することはできません。しかし、コンパイルされた/解釈された/ JIT行はかなり不鮮明になる可能性があります。

1
Javaは驚くべき移植性があるため、よく宣伝されています。これは、JVMがコンパイルされているシステム(つまり、JVM(Cで記述)がコンパイルされているシステム)に移植可能です。Cコードを同じ方法で処理することを妨げるものは何もありませんが、努力を正当化するためにそれを行うことによる十分な利点を誰も見ていません。
ピートベッカー

2
私はこのビットに戸惑っています:「Cがコンパイルされないようにするもの/ [...]」。えっと、何も?
Andres F.

1
最近のCコンパイラはかなり高速なので、「make myprog.c; myprog」はおそらくほとんどのインタプリタよりも高速に実行されます。
ジェームズアンダーソン

回答:


18

Cは私が中級言語と呼ぶものです。その目的は、「非常に高レベルのアセンブラー」として機能することです。そのため、コンパイラーのターゲットとして非常にうまく機能し、移植性を非常にうまく受け入れます。

歴史的に、インタープリターは通常、メソッド呼び出しのコンテキストで高級言語で使用されてきました。最も単純な形式では、インタプリタはソース言語の各キーワードとそれに関連するトークンを解析し、それをメソッド呼び出しとパラメータに変換するだけです。実際には、ほとんどのインタープリターが行うことは、ソース言語を中間表現に変換することであり、解釈されるのはその表現です。

Cが解釈またはJittされるのを止めるのは何ですか? 何もない。 しかし、それはCの存在理由ではありません。


6

まず、SunのJVMがCで記述されていることは注目に値します。移植性が必要な場合、Cは非常に人気のある言語です。

多くのC プログラムは移植可能ではありませんが、C 言語は移植可能です。これは、Cがプログラマにそれほど多くの制限を課したり、多くの仮定を行ったりしないためです。Cプログラマーが自分のプログラムを移植可能にしたい場合は、自分でそれらの制限を課す必要があります。

実際には、Javaがあなたに課している制限を守ることはそれほど難しいことではありません。ほとんどの場合、エンディアンとプリミティブサイズに注意し、プラットフォーム固有のライブラリではなくGTK +などのポータブルライブラリを使用することです。

GTK +ターゲットと仮想マシン(おそらくJVM)をサポートするCコンパイラを作成し、既存のコードをほとんど変更せずに機能させることができます。実際、ガベージコレクションがなければ、C仮想マシンの方がはるかに単純です。なぜあなたがしたいのですか?

逆に、Javaをネイティブコードにコンパイルすることも同様に実行可能です。これは基本的にJITが行うことです。なぜあなたがしたいのですか?「という理由だけで」それを行うためのペットプロジェクトがあると確信していますが、それらは真剣に使用されていません。


5

あなたが言った:

Javaは、その驚くべき移植性でしばしば賞賛されています。これは、JVMが原因だと思います。

そして、最初の文では、あなたは間違っています。JVMのため、Javaは移植できません。Javaは移植性があります。これは、Java言語が、プログラムの振る舞いに実装者にゆとりがないように定義されているためです。

例として、Javaには2つのタイプ「int」(符号付き32ビット整数)と「long」(符号付き64ビット整数)があります。CおよびC ++には、「int」(少なくとも16ビットの符号)、「long」(少なくとも32ビットの符号)、および「long long」(少なくとも64ビットの符号)があります。これは、Cがさまざまなプロセッサ上で実行されることになっており、それらが異なる動作をすることができるためです。

Cはこれらの型の固定サイズを定義することができます。もしそうなら、36ビットプロセッサはC言語を実装できなかったでしょう。そして、Javaを実際に実装することはできません。そのため、Cはこの言語をさまざまな異なるコンピューターで使用できるようにしました。これにより、移植できないコードの作成が可能になることは避けられません。それは言語の問題です。


36ビットマシンで32ビット演算をエミュレートして、すべての演算の結果に0xFFFFFFFFをAND演算して32ビットに切り捨てることができます。したがって、これらのマシン Javaを実装できますが、Javaがnonetベースのタイプを許可した場合よりも遅くなります。
dan04 2015年

4

Javaは、その名のとおり、実際のマシンではない Java仮想マシンをターゲットにしているため、移植性が非常に高くなっています。さまざまな種類の実際のマシンのアーキテクチャに仮想マシンを実装できるため、JVMベースのプログラムは移植性が高いです。

一方、Cは完全なハードウェアアクセスを必要とするオペレーティングシステムを実装する特定の目的のために作成されたため、実際のハードウェアに対して実行するように特別に設計されています。これは、Cコードは設計上特にポータブルではないことを意味します。Cプログラムをあるプラットフォームから別のプラットフォームに移植する場合、ターゲットアーキテクチャに固有のさまざまな部分をある程度書き換える必要があります。


7
Cは移植性が高い。ターゲットプラットフォームで再コンパイルする必要があるだけであり、具体的かつ意図的に移植性のないこれらのいくつかのビットを避けます。
ロバートハーベイ

5
@RobertHarvey:... さまざまなプリミティブのサイズと同じくらい基本的なものなどですか?;)
メイソンウィーラー

2
はい、そういうことです。問題が存在するのは残念ですが、言語は他のすべての方法で完全に移植可能であり、プリミティブサイズがすべてのプラットフォームで機能することを確認する方法があります。
ロバートハーベイ

3
@RobertHarvey:Cは移植可能なプログラムを書くことを可能にするが、それは本質的にそれを簡単にするわけではない。
ドクターブラウン

2
@RobertHarvey:宗教戦争を始めたいですか?;-)私のお気に入りの移植可能な言語はPythonです。
ドクブラウン

3

実際には解釈されたCのバージョンがありますが、それらは主に、実動システムではなく迅速な実験に使用することを目的としています。

結局のところ、小さくて高速で静的な実行可能ファイルを取得しないと、なぜCのすべての特異性に悩まされるのでしょうか。


3

理論的には、CとJavaの両方をネイティブコードにコンパイル、解釈、または仮想マシンにコンパイルできます。

Cが仮想マシンにコンパイルされない技術的な理由は、標準の仮想Cマシンが存在しないためです。

そして、誰も仮想Cマシンを定義したり、Java仮想マシンにコンパイルしたりすることを望んでいないようです(これは完全に可能です)。おそらく、Cを使用する誰もがその比類のない速度を失いたくないためです。おそらく、Cはコンパイル(ソースを配布して再コンパイルして実行する)によって移植性を簡単に実現できるオープンソースコミュニティで最も強力であるため、クローズドとして実行(バイナリを配布して実行する)の移植性の必要性を感じませんソース開発者が行います。


1

これは実際に行われます。LLVMへのコンパイルをサポートする主要なコンパイラーがあります(clangはそうですが、gccも同様です)。JavaコードがJITされたバイトコードにコンパイルされるのと同じように、そのLLVMをJITすることができます。

ただし、Cと比較してjavaが「クロスプラットフォーム」になるのは、Javaに多くのプラットフォームに移植された大きなランタイムライブラリがあることです。Cは明示的にこのパラダイムに従っていません。


注意してコーディングすれば、POSIXを使用したCは(あらゆるPOSIXシステムに)移植可能です。
Basile Starynkevitch、2015年

0

JavaとCの間にはいくつかの大きな違いがあります。Javaは、Java仮想マシン(JVM)を介してオペレーティングシステムから分離されています。JVMは、プログラムからオペレーティングシステムを抽象化します。JavaアプリケーションはJVMにメモリのチャンクを要求し、JVMはOSにそのメモリを要求します。さまざまなプラットフォーム/オペレーティングシステム用の多くのJVMがあります。JVMは、同じJavaプログラムを異なるプラットフォームで実行できるようにするものです。

Cでは、OSの分離はありません。Cプログラムは(通常)OSの上で直接実行され、直接OS呼び出しを行います。これにより、Cプログラムが特定のオペレーティングシステム/プラットフォームに関連付けられます。重要なプログラムは、オペレーティングシステムを呼び出します。さらに、Cプログラムは、ハードウェア固有のマシンコードにコンパイルされます。x86用にコンパイルされたCプログラムは、ARMプロセッサで直接実行できません。


1
Javaは、プラットフォームに依存しないバイトコードにコンパイルされます。バイトコードは、(理論的には、少なくとも)任意のプラットフォームの任意のJVMで実行できます。Cは、対象とするすべてのCPUのアセンブリ言語にコンパイルされます(したがって、x86アーキテクチャを対象としている場合、Cコンパイラはx86アセンブラを作成します。そのアーキテクチャを対象としている場合は、amd64アセンブラ、またはARMアセンブラなどを作成します)。次に、アセンブリ言語はオブジェクトファイル(実際にはバイナリアセンブラ)に変換され、実行可能ファイル(ターゲットマシンに応じていくつかの異なる形式)にリンクされます。
Craig

1
Java言語仕様には、JVMについて何も述べていないため、JVMを使用しないJavaの実装があります。Androidでは、JavaプログラムはDalvik VM(現在は廃止)またはAndroidランタイムで実行され、CLI用のJavaの実装、ECMAScriptにコンパイルされる実装、およびネイティブコードにコンパイルされる実装があります。JVMにコンパイルするCコンパイラがあります。ECMAScriptにコンパイルするCコンパイラがあります。C通訳がいます。
イェルクWミッターク
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.