web-dev-qa-db-ja.com

Cコンパイラが少ないのはなぜですか?

Cは、世界で最も広く使用されている言語の1つです。既存のコードの大部分を占めており、膨大な量の新しいコードに引き続き使用されています。ユーザーに愛され、広く移植されているため、Cを実行できるのはプラットフォームの非公式定義の多くであり、ファンからも高く評価されています。比較的クリーンな機能のセットを備えた「小さな」言語であるため。

では、すべてのコンパイラはどこにあるのでしょうか?

デスクトップには、(現実的に)2つがあります。GCCとClangです。数秒間考えてみると、おそらくIntelも存在することを覚えているでしょう。他の人はほんの一握りで、平均的な人が名前を付けるにはあまりにあいまいであり、ほとんどすべての場合、最近の言語バージョン(または多くの場合、明確に定義された言語サブセットでさえ、単に「サブセット」)をサポートすることを気にしません。 このリストのメンバー の半分は、歴史的な脚注です。残りのほとんどは非常に特殊化されており、実際には完全な言語を実装していません。実際にオープンソースであると思われるものはほとんどありません。

SchemeとForth-ファンのために愛されている他の小さな言語-おそらく実際のユーザーよりも多くのコンパイラーを持っています。 [〜#〜] sml [〜#〜] のようなものでも、Cよりも「深刻な」実装を選択できます。一方、 (未完成)Cコンパイラの発表は、検証 は実際にはかなり否定的な応答をいくつか目にします ベテランの実装 C99に追いつくのに十分な貢献者を得るのに苦労します。

どうして? Cの実装は難しいですか? C++ではありません。ユーザーは、どの複雑性グループに該当するか(つまり、実際にはSchemeよりもC++に近いということ)について、非常に歪んだ考えを持っていますか?

72
anon

現在、実際のCコンパイラは 最適化コンパイラ である必要があります。特に、現在の processors は非常に複雑であるため(Cはもはやハードウェアに近い言語ではないため) out-of-orderpipelinedsuperscalar 、with complex caches[〜#〜] tlb [〜#〜] 、つまり 命令スケジューリング などが必要です...)。今日のx86プロセッサは、同じマシンコードを実行できても、前世紀のi386プロセッサとは異なります。 Cは低水準言語ではありません(お使いのコンピュータは高速なPDP-11ではありません) David Chisnallによる論文を参照してください。

tinyccnwcc のような単純な非最適化Cコンパイラを使用している人はほとんどいません。なぜなら、最適化コンパイラが提供できるものより数倍遅いコードを生成するからです。

最適化コンパイラのコーディングは困難です。 GCCとClangの両方が「ソース言語に中立な」コード表現(GCCの場合はGimple、Clangの場合はLLVM)を最適化していることに注意してください。優れたCコンパイラの複雑さは解析段階ではありません!

特に、C++コンパイラを作成することは、Cコンパイラを作成することよりも難しくありません。C++の解析と内部コード表現への変換は複雑です(C++仕様は複雑であるため)。複雑な(GCC内:ミドルエンドの最適化、ソース言語とターゲットプロセッサニュートラル、コンパイラの大部分を構成し、残りはseveralseveralプロセッサ用の言語とバックエンド。したがって、ほとんどの最適化Cコンパイラは、C++、Fortran、Dなどの他の言語もコンパイルできます。GCCのC++固有の部分はコンパイラの約20%です...

また、C(またはC++)は非常に広く使用されているため、公式の標準に厳密に準拠していない場合でも、コードがコンパイル可能であることが期待されます。それの)。 CompCert が証明されたCコンパイラ、およびCのより正式な semantics に関心のある Frama-C 静的アナライザーも確認してください。

そして、最適化は long-tail 現象です。いくつかの単純な最適化を実装することは簡単ですが、コンパイラを競争力のあるものにすることはできません!競争力のある実際のコンパイラを実現するには、さまざまな最適化を実装し、それらを巧妙に整理して組み合わせる必要があります。つまり、実際の最適化コンパイラは複雑なソフトウェアでなければなりません。ところで、GCCとClang/LLVMの両方には、いくつかの内部専用C/C++コードジェネレーターがあります。また、どちらも巨大な獣(数百万のコードのソース行、毎年数パーセントの成長率)であり、大規模な開発者コミュニティ(数百人、ほとんどフルタイム、または少なくともハーフタイム)がいます。

no(私の知る限り)マルチスレッドCコンパイラがsomeコンパイラーの一部を並行して実行することができます(例えば、プロシージャー内最適化、レジスター割り当て、命令スケジューリング...)。そして、make -jは必ずしも十分ではありません(特に [〜#〜] lto [〜#〜] の場合)。

また、Cコンパイラのコーディングにゼロから資金を調達することは困難であり、そのような努力は数年続く必要があります。最後に、ほとんどのCまたはC++コンパイラは今日のフリーソフトウェアである(スタートアップによって販売される新しい独自のコンパイラの市場はもはや存在しない)、または少なくとも独占的な商品( Microsoft Visual C++ など)であり、無料であるコンパイラーにはソフトウェアがほとんど必要です(多くの異なる組織からの貢献が必要なため)。

私はCコンパイラをフリーソフトウェアとしてゼロから動作させるための資金を得ることを嬉しく思いますが、今日はそれが可能であると信じるほど世間知らずではありません!

154

C実装の数が少ないという根本的な仮定に異議を唱えたいと思います。

私はCさえ知りません、私はCを使用しません、私はCコミュニティのメンバーではありません、それでも、あなたが言ったいくつかのコンパイラよりはるかに多くを知っています。

まず第一に、おそらくデスクトップ上でGCCとClangの両方を完全に小型化するコンパイラーがあります。MicrosoftVisualC。OSXとLinuxの両方がデスクトップ上で作られている進出にもかかわらず、iOSとAndroid以前の従来のデスクトップユーザーから「盗まれ」、Windowsは依然としてthe支配的なデスクトップOSであり、WindowsデスクトップCプログラムの大部分はおそらくコンパイルされていますMicrosoftツールを使用する。

従来、すべてのOSベンダーとすべてのチップベンダーには独自のコンパイラがありました。 OSベンダーとしてのMicrosoftにはMicrosoft Visual Cがあります。OSベンダーとチップベンダーの両方として、IBMにはXLC(AIXのデフォルトシステムコンパイラであり、AIXとi/OSの両方をコンパイルするコンパイラ)があります。 。インテルには独自のコンパイラーがあります。 Sun/Oracleは、Sun Studioに独自のコンパイラーを持っています。

次に、PathScaleやThe Portland Groupのような高性能コンパイラーベンダーがあり、そのコンパイラー(およびOpenMPライブラリー)は数値計算に使用されます。

Digital Marsもまだ稼働しています。 Walter Brightは、(ほとんどの場合)プロダクション品質のC++コンパイラーを自分で作成した地球上で唯一の人物であるという独特の特徴を持っていると思います。

最後に重要なことですが、組み込みマイクロコントローラー用のすべての専用コンパイラーがあります。 IIRCは、デスクトップ、モバイル、サーバー、ワークステーション、およびメインフレームのCPUが、コンピューティングの歴史全体で販売されているよりも、毎年多くのマイクロコントローラーを販売しています。したがって、これらは間違いなくニッチ製品ではありません

TruffleC 、Truffleを使用して作成されたJVM(!)で実行されるCインタープリター(!) ASTインタープリターフレームワークは、コンピューター言語ベンチマークゲーム全体で、GCCおよびClang(特定のベンチマークで最も速い方)よりも7%遅く、マイクロベンチマークの両方よりも高速です。 TruffleCを使用して、TruffleチームはJRuby + Truffleのバージョンを取得し、実際のC Ruby実装よりも速くRuby C拡張を実行できました!

だから、これらはあなたがリストしたものに加えて6つの実装であり、Cについて何も知らなくても頭の上から名前を付けることができます。

70
Jörg W Mittag

コンパイラーはいくつ必要ですか?

機能セットが異なる場合は、移植性の問題が発生します。それらが商品化されている場合は、「デフォルト」(GCC、Clang、またはVS)を選択します。過去5%のパフォーマンスを重視する場合は、ベンチマークがオフになります。

あなたがレクリエーションでまたは研究目的でプログラミング言語の仕事をしているなら、それはより現代的な言語である可能性が高いです。したがって、SchemeとML向けのおもちゃコンパイラーの急増です。 OCamlは、おもちゃ以外の非学術的な使用のためにいくつかの牽引力を持っているようですが。

これは言語によって大きく異なることに注意してください。 Javaには基本的にSun/Oracleツールチェーンがあり、GNU one。Pythonにはさまざまなコンパイラがあり、どれも実際には尊重されていません標準のインタープリターと比較してください。RustとGoにはそれぞれ1つの実装しかありません。C#にはMicrosoftとMonoがあります。

8
pjc50

C/C++は、共通仕様の3つの主要な実装があるという点で、コンパイルされた言語の中でユニークです。

あまり使用されないものはすべて却下するというルールに従うと、他のすべてのコンパイル済み言語には0から1があります。

そして、「コンパイル済み」を指定する必要がある唯一の理由は、javascriptだと思います。

6
soru

では、ターゲット言語は何ですか?

SMLコンパイラは、多くの場合、CまたはLLVM(またはリンク、JVM、JavaScriptなど)のようなものをターゲットにしています。

Cをコンパイルしているのは、JVMを使用するためではありません。あなたはCよりも何か悪いに行くでしょう。はるかに悪いです。そして、あなたはすべてのターゲットプラットフォームについて、その小さな地獄を何度も複製します。

もちろん、CはC++ではありませんが、SchemeよりC++に近いと思います。未定義の動作の悪さの独自のサブセットがあります(組み込みタイプのサイズを調べています)。そして、その細かい点を台無しにした場合(または「正しく」しかし予期せずにそれを実行した場合)、自分がどれほどひどいかを知らせる重要なシステムに何十年もの既存のコードがあります。 SMLコンパイラーを台無しにしても、動作しません-そして誰かmightに気付くでしょう。いつか。

5
Telastyn