Javaは、その驚くべき移植性でしばしば賞賛されています。これは、JVMが原因だと思います。私の質問は、Cがコンパイル/解釈/ JITされるのを阻止するものです。もしそうなら、Cは1度だけ記述して、あなたが持っているどのデバイスでも動作させることができます。しかし、これはCプログラムを処理するための一般的なメカニズムではありません。
もちろん、このようにCを処理することの欠点は何ですか?もちろん移植性以外に、このようにJavaを処理してマシンコードにコンパイルしないことの利点は何ですか?
Javaは、その驚くべき移植性でしばしば賞賛されています。これは、JVMが原因だと思います。私の質問は、Cがコンパイル/解釈/ JITされるのを阻止するものです。もしそうなら、Cは1度だけ記述して、あなたが持っているどのデバイスでも動作させることができます。しかし、これはCプログラムを処理するための一般的なメカニズムではありません。
もちろん、このようにCを処理することの欠点は何ですか?もちろん移植性以外に、このようにJavaを処理してマシンコードにコンパイルしないことの利点は何ですか?
回答:
Cは私が中級言語と呼ぶものです。その目的は、「非常に高レベルのアセンブラー」として機能することです。そのため、コンパイラーのターゲットとして非常にうまく機能し、移植性を非常にうまく受け入れます。
歴史的に、インタープリターは通常、メソッド呼び出しのコンテキストで高級言語で使用されてきました。最も単純な形式では、インタプリタはソース言語の各キーワードとそれに関連するトークンを解析し、それをメソッド呼び出しとパラメータに変換するだけです。実際には、ほとんどのインタープリターが行うことは、ソース言語を中間表現に変換することであり、解釈されるのはその表現です。
Cが解釈またはJittされるのを止めるのは何ですか? 何もない。 しかし、それはCの存在理由ではありません。
まず、SunのJVMがCで記述されていることは注目に値します。移植性が必要な場合、Cは非常に人気のある言語です。
多くのC プログラムは移植可能ではありませんが、C 言語は移植可能です。これは、Cがプログラマにそれほど多くの制限を課したり、多くの仮定を行ったりしないためです。Cプログラマーが自分のプログラムを移植可能にしたい場合は、自分でそれらの制限を課す必要があります。
実際には、Javaがあなたに課している制限を守ることはそれほど難しいことではありません。ほとんどの場合、エンディアンとプリミティブサイズに注意し、プラットフォーム固有のライブラリではなくGTK +などのポータブルライブラリを使用することです。
GTK +ターゲットと仮想マシン(おそらくJVM)をサポートするCコンパイラを作成し、既存のコードをほとんど変更せずに機能させることができます。実際、ガベージコレクションがなければ、C仮想マシンの方がはるかに単純です。なぜあなたがしたいのですか?
逆に、Javaをネイティブコードにコンパイルすることも同様に実行可能です。これは基本的にJITが行うことです。なぜあなたがしたいのですか?「という理由だけで」それを行うためのペットプロジェクトがあると確信していますが、それらは真剣に使用されていません。
あなたが言った:
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はこの言語をさまざまな異なるコンピューターで使用できるようにしました。これにより、移植できないコードの作成が可能になることは避けられません。それは言語の問題です。
Javaは、その名のとおり、実際のマシンではない Java仮想マシンをターゲットにしているため、移植性が非常に高くなっています。さまざまな種類の実際のマシンのアーキテクチャに仮想マシンを実装できるため、JVMベースのプログラムは移植性が高いです。
一方、Cは完全なハードウェアアクセスを必要とするオペレーティングシステムを実装する特定の目的のために作成されたため、実際のハードウェアに対して実行するように特別に設計されています。これは、Cコードは設計上特にポータブルではないことを意味します。Cプログラムをあるプラットフォームから別のプラットフォームに移植する場合、ターゲットアーキテクチャに固有のさまざまな部分をある程度書き換える必要があります。
実際には解釈されたCのバージョンがありますが、それらは主に、実動システムではなく迅速な実験に使用することを目的としています。
結局のところ、小さくて高速で静的な実行可能ファイルを取得しないと、なぜCのすべての特異性に悩まされるのでしょうか。
理論的には、CとJavaの両方をネイティブコードにコンパイル、解釈、または仮想マシンにコンパイルできます。
Cが仮想マシンにコンパイルされない技術的な理由は、標準の仮想Cマシンが存在しないためです。
そして、誰も仮想Cマシンを定義したり、Java仮想マシンにコンパイルしたりすることを望んでいないようです(これは完全に可能です)。おそらく、Cを使用する誰もがその比類のない速度を失いたくないためです。おそらく、Cはコンパイル(ソースを配布して再コンパイルして実行する)によって移植性を簡単に実現できるオープンソースコミュニティで最も強力であるため、クローズドとして実行(バイナリを配布して実行する)の移植性の必要性を感じませんソース開発者が行います。
これは実際に行われます。LLVMへのコンパイルをサポートする主要なコンパイラーがあります(clangはそうですが、gccも同様です)。JavaコードがJITされたバイトコードにコンパイルされるのと同じように、そのLLVMをJITすることができます。
ただし、Cと比較してjavaが「クロスプラットフォーム」になるのは、Javaに多くのプラットフォームに移植された大きなランタイムライブラリがあることです。Cは明示的にこのパラダイムに従っていません。
JavaとCの間にはいくつかの大きな違いがあります。Javaは、Java仮想マシン(JVM)を介してオペレーティングシステムから分離されています。JVMは、プログラムからオペレーティングシステムを抽象化します。JavaアプリケーションはJVMにメモリのチャンクを要求し、JVMはOSにそのメモリを要求します。さまざまなプラットフォーム/オペレーティングシステム用の多くのJVMがあります。JVMは、同じJavaプログラムを異なるプラットフォームで実行できるようにするものです。
Cでは、OSの分離はありません。Cプログラムは(通常)OSの上で直接実行され、直接OS呼び出しを行います。これにより、Cプログラムが特定のオペレーティングシステム/プラットフォームに関連付けられます。重要なプログラムは、オペレーティングシステムを呼び出します。さらに、Cプログラムは、ハードウェア固有のマシンコードにコンパイルされます。x86用にコンパイルされたCプログラムは、ARMプロセッサで直接実行できません。