web-dev-qa-db-ja.com

C#は部分的に解釈されていますか、実際にコンパイルされていますか?

これについて多くの矛盾する情報があります。 C#がコンパイルされる(ILにコンパイルされ、実行時にネイティブコードにコンパイルされる)と言う人もいれば、.NETが必要であると解釈されると言う人もいます。 EN Wikiのコメント:

多くの解釈済み言語は、最初に何らかの形式の仮想マシンコードにコンパイルされ、実行時にネイティブコードに解釈またはコンパイルされます。

だから私はかなり混乱しています。誰もこれを明確に説明できますか?

63
John V

C#は、c#コンパイラーによってILにコンパイルされます。

このILは、必要に応じて、ホストマシンのネイティブアセンブリ言語にジャストインタイム(JIT)でコンパイルされます。ただし、代わりにILを解釈する.NETランタイムを作成することは可能です。これが行われたとしても、c#はコンパイルされた言語であると主張します。

65
Simon

純粋にコンパイルされた言語にはいくつかの利点があります。速度、原則として、多くの場合、作業セットのサイズ。純粋に解釈された言語にはいくつかの利点があります。その場で編集できる明示的なコンパイル段階を必要としない柔軟性、および多くの場合より簡単な移植性。

この場合、Jitted言語は妥協点に適合します。

それが、私たちがジッター言語をコンパイルまたは解釈するものと考える理由であるのはそれだけです。

C#は、ASP.NETで発生するように、初回実行時にコンパイルすることもできます。これにより、C#はその場合にほぼ解釈されます(ただし、ILにコンパイルされ、この場合はjittedされます)。確かに、この場合に解釈されるほとんどすべての利点(従来のASPで使用されているVBScriptまたはJScriptと比較してください)と、コンパイルされた利点の多くがあります。

厳密に言えば、言語はjitted、解釈、またはコンパイルされたqua言語ではありません。 NGen C#をネイティブコードにできます(ただし、アセンブリを動的に読み込むようなことを行う場合でも、ILとjittingを使用します)。 CまたはC++のインタプリタを作成できます(数人が作成しました)。しかし、最も一般的な使用例では、C#はILにコンパイルされ、その後ジッターされます。これは、インタープリターやコンパイルの古典的な定義ではありません。

36
Jon Hanna

意見に基づくセマンティクスとステートメントが多すぎます。

まず、C#はインタープリター言語ではありません。 CLRとJVMは「ランタイム」または「ミドルウェア」と見なされますが、Perlのようなものには同じ名前が適用されます。これは名前に関係する人々の間で多くの混乱を引き起こします。

ランタイムを参照する「インタープリター」という用語は、一般に、既存のコードが一部の非ネイティブコードを解釈することを意味します。 2つの大きなパラダイムがあります。解析は生のソースコードを読み取り、論理的なアクションを実行します。バイトコードの実行では、最初にコードを非ネイティブバイナリ表現にコンパイルします。これにより、解釈に必要なCPUサイクルが大幅に少なくなります。

Javaはもともとバイトコードにコンパイルされ、その後インタープリターを通過しました。現在、JVMはバイトコードを読み取り、ジャストインタイムでネイティブコードにコンパイルします。 CILは同じことを行います。CLRは、ジャストインタイムコンパイルをネイティブコードに使用します。

ソースコードの実行、バイトコードの実行、ネイティブへのコンパイル、ジャストインタイムコンパイル、コンパイラーを介したソースコードのジャストインタイムネイティブへの実行などのすべての組み合わせを検討してください。言語がコンパイルまたは解釈されるかどうかのセマンティクスは無意味になります。

例として、多くのインタープリター言語はジャストインタイムのバイトコードコンパイルを使用します。 C#はCILにコンパイルされ、JITはネイティブにコンパイルされます。対照的に、Perlはスクリプトを直ちにバイトコードにコンパイルし、インタープリターを介してこのバイトコードを実行します。 C#バイトコード形式でのみC#アセンブリを実行できます。生のソースコード形式でのみPerlスクリプトを実行できます。

ジャストインタイムコンパイラーは、多くの外部および内部インストルメンテーションも実行します。ランタイムはさまざまな機能の実行を追跡し、コードレイアウトを調整して、特定の実行フローに合わせてブランチとコード編成を最適化します。つまり、JITコードは実行時にコードの実際の実行ケースに合わせて最適化戦略を調整するため、JITコードはネイティブコンパイルされたコードよりも高速に実行できます(C++は通常、またはC#はIL2CPPを介して実行されます)。

コンピュータプログラミングの世界へようこそ。それを非常に複雑にし、すべてに説明のない名前を付けることにしました。目的は、実用的な意味を持たない単語の定義をめぐるフレームワークを作成することです。

14
John Moser

こちらをご覧ください: http://msdn.Microsoft.com/library/z1zx9t92

C#で記述されたソースコードは、CLI仕様に準拠した中間言語(IL)にコンパイルされます。

(...)

C#プログラムが実行されると、アセンブリがCLRに読み込まれ、マニフェストの情報に基づいてさまざまなアクションが実行される場合があります。その後、セキュリティ要件が満たされると、CLRはジャストインタイム(JIT)コンパイルを実行して、ILコードをネイティブマシン命令に変換します。

11
psur

コンパイルされたEXEがソースコードからマシンコードに移行していると感じたり、学んだり、古い学校である場合は、C#が解釈されます。コンパイル済みとは、ソースコードをバイトコードなどの他のコードに変換することを意味すると考える場合、変換されます。私にとっては、ランタイム処理がビルドされたOSで動作するために必要なものはすべて解釈されます。

10
ChicagoBob

最初に、解釈およびコンパイルの定義を理解しましょう。

"Compile"(コードを参照する場合) は、ある言語から別の言語にコードを翻訳することを意味します。通常、人間が読み取れるソースコードから、ターゲットプロセッサが処理できるマシンコードへ。

"Interpret"(コードを参照する場合) また、ある言語から別の言語にコードを翻訳することを意味します。しかし、今回は通常、人間が読み取れるソースコードから中間コードに移行するために使用されます。中間コードは、それをマシンコードに解釈する仮想マシンによって取得されます。

ただ明確にします
ソースコード->コンパイラ->マシンコード
ソースコード->コンパイラ->バイトコード->インタープリター->マシンコード

理論的には、どの言語でも interpreted または compiled になります。通常、Javaは、Java仮想マシンによってマシンコードに解釈されるバイトコードにコンパイルされます。C#は、CLRによってコンパイルされるバイトコードに解釈されます。共通言語ランタイム、別の仮想マシン。

間違いなく、すべてがマーケティングの仕掛けです。 「解釈された」という用語が追加されました(または、少なくとも、使用量が増えました)。 ジャストインタイムコンパイル がいかに素晴らしかったかを示すのに役立ちます。ただし、「コンパイル済み」を使用することもできます。区別は、技術的な性質のものではなく、英語とビジネストレンドの研究です。

4
Philip

すべてではありませんが、ほとんどの言語では、cpuがそれを理解して実行できるように、スクリプトをマシンコードに変換するインタープリターが必要です。

各言語は翻訳プロセスを異なる方法で処理します!

たとえば、「AutoIt」は100%通訳言語であると説明できます。

どうして?

スクリプトの実行中は「AutoIt」インタープリターが常に必要だからです!以下の例を参照してください。

Loop, 1000
Any-Code

「AutoIt」インタープリターは「Any-Code」をマシンコードに1000回翻訳する必要があり、これにより「AutoIt」は自動的に遅い言語になります!

一方、C#は翻訳プロセスを異なる方法で処理します。C#のインタープリターは、スクリプトの実行前に1回だけ必要になり、その後はスクリプトの実行中に不要になります。

C#のインタープリターは、「Any-Code」を一度だけマシンコードに翻訳する必要があります。これにより、「C#」が高速言語に自動的に変更されます。

だから基本的に、

  • スクリプトの実行中にインタープリターを必要とする言語は「解釈言語」です!

  • インタプリタを1回だけ(スクリプトの実行前に)必要とする言語は、「コンパイル済み言語」です!

最後に、

  • 「AutoIt」は「解釈された言語」です!

  • 「C#」は「コンパイル言語」です!

2
User

C#は両方であり、その有効期間中に解釈およびコンパイルされます。 C#は、VMによって解釈される仮想言語にコンパイルされます。

この混乱は、「コンパイルされた言語」というファジーな概念に起因しています。

「コンパイルされた言語」は、ある意味で誤った呼び名です。コンパイルまたは解釈されるのは、言語ではなくランタイムのプロパティだからです。

例えばCインタープリターを作成できますが、C実装はマシンコードにコンパイルされ、コンパイルを念頭に置いて言語が設計されているため、人々は通常「コンパイル言語」と呼びます。

2
ajfabbri

これはかなり古いトピックだと思います。

私の観点からは、解釈されたコードはインタープリターを通過し、行ごとに変換され、同時に実行されます。 JavaScriptの例のように、それは解釈されたコードであり、JavaScriptの行がエラーにぶつかると、スクリプトはただ壊れます。

コンパイルされたコードは、コンパイラを通過し、最初に実行せずに、すべてのコードを一度に別の形式のコードに変換します。実行は別のコンテキストで行われます。

1
Jonny

インタープリターの定義に同意する場合"コンピューターサイエンスでは、インタープリターはプログラミング言語またはスクリプト言語で書かれた命令を直接実行するコンピュータープログラムです。機械語プログラムにコンパイルされています。"疑いの余地はありません。C#はインタプリタ言語ではありません。

ウィキペディアの通訳者

0
Angelo Mascaro

JavaのようなC#には、ハイブリッド言語プロセッサがあります。ハイブリッドプロセッサは、解釈とコンパイルの両方のジョブを実行します。

0
P.Brian.Mackey

C#はコンパイル可能な言語です。

おそらく、私もそういう意見に出会ったので、C#言語の通訳があると誰かが考えるという事実は、おそらく次のようなプロジェクトによるものです。

C#インタープリターコンソール

または、例えば、有名な

LinqPAD

コードの行だけを書いて実行できるので、 Python 言語のようにnot true。 (ワークフローの観点から)通常のコンパイル可能なプログラミング言語のように、それらの行をコンパイルして実行します。

0
Tigran

コンピュータはバイナリコードしか実行できないため、どの言語でも、ある時点でバイナリコードが生成されます。問題は、言語はバイナリコードでプログラムを作成できるかどうかです。 「はい」の場合、コンパイル済み言語です。「コンパイル済み言語」の「コンパイル済み」とは、いくつかの中間コードへの変換ではなく、バイナリコードへのコンパイルを意味します。言語がプログラムのこのような中間コードの生成につながる場合、このコードからバイナリコンパイルを実行するための追加のソフトウェアが必要になります。それは、インタープリター言語です。プログラムは、C#によって「コンパイル」され、他のソフトウェアがまったくインストールされていないマシンで直接実行できますか?いいえの場合、インタープリター言語です。インタープリター言語の場合、このメカニズムはそのような言語の柔軟性の基礎であるため、ほとんどの場合、動的な方法で基礎となるバイナリコードを生成するインタープリターです。レム:インタプリタがOSにバンドルされているため、時々明白に見えません

0
ClearMind