GNUコンパイラ コレクション( GCC、旧称GNU C コンパイラ) は、さまざまなプログラミング言語、ハードウェア アーキテクチャ、オペレーティングシステムをサポートするGNU プロジェクトのコンパイラのコレクションです。フリー ソフトウェア財団(FSF) は、GNU 一般公衆ライセンス(GNU GPL)の下でGCC をフリー ソフトウェアとして配布しています。GCC は、 GNUおよびLinux カーネルに関連するほとんどのプロジェクトで使用されるGNU ツール チェーンの重要なコンポーネントです。2019 年の時点で約 1500 万行のコードを持つ GCC は、現存する最大のフリー プログラム 1 つです。[ 4 ]ツールとしても模範としても、フリー ソフトウェアの成長において重要な役割を果たしてきました。
1987年にリチャード・ストールマンによって初めてリリースされたGCC 1.0は、C言語のみを扱っていたため、GNU Cコンパイラと呼ばれていました。[ 1 ]同年12月にはC++のコンパイルにも対応しました。その後、 Objective-C、Objective-C++、Fortran、Ada、Go、D、Modula-2、Rust、COBOL、ALGOL 68などのフロントエンドが開発されました。 [ 6 ] CおよびC++コンパイラでは、OpenMPおよびOpenACC仕様もサポートされています。 [ 7 ] [ 8 ]
GCCはGNUオペレーティングシステムの公式コンパイラであるだけでなく、ほとんどのLinuxディストリビューションを含む、他の多くの最新のUnixライクなコンピュータオペレーティングシステムの標準コンパイラとしても採用されています。ほとんどのBSDファミリーのオペレーティングシステムもリリース後すぐにGCCに切り替えましたが、その後、FreeBSDとApple macOSはライセンス上の理由から主にClangコンパイラに移行しました[ 9 ] 。 [ 10 ] [ 11 ] [ 12 ] GCCはWindows、Android、iOS、Solaris、HP-UX、AIX、およびMS-DOS互換オペレーティングシステムのコードもコンパイルできます[ 13 ]。
GCCは、他のどのコンパイラよりも多くのプラットフォームと命令セットアーキテクチャに移植されており、フリーソフトウェアとプロプライエタリソフトウェアの両方の開発ツールとして広く利用されています。GCCは、 ARMベースやPower ISAベースのチップを含む、多くの組み込みシステムでも利用可能です。
1983 年後半、 GNUオペレーティングシステムのブートストラップを試みる中で、リチャード・ストールマンは、アムステルダムコンパイラキット(フリー大学コンパイラキットとしても知られる)の作者であるアンドリュー・S・タネンバウムに、そのソフトウェアを GNU で使用する許可を求めました。タネンバウムが、コンパイラ自体は無料ではなく、大学のみが無料であると彼に伝えたとき、ストールマンは別のコンパイラに取り組むことにしました。[ 14 ]彼の最初の計画は、レン・タワーらの助けを借りて、ローレンス・リバモア国立研究所の既存のコンパイラをPastel言語用に Pastel で書き直すことでした。[ 15 ] [ 16 ]ストールマンは、リバモア コンパイラ用の新しい C フロントエンドを作成しましたが、スタック領域がメガバイト必要であることに気づき、 64 KB を超えるスタック領域を許可しない68000 Unix システムでは不可能であることから、新しいコンパイラをゼロから作成する必要があると結論付けました。[ 15 ] Pastel コンパイラのコードは GCC には採用されなかったが、Stallman は Pastel で書いた C フロントエンドを使用した。[ 15 ] [ 17 ]
GCC は 1987 年 3 月 22 日にMITからFTPで初めてリリースされました。[ 18 ] Stallman が著者として記載されていますが、パーサー、RTL ジェネレータ、RTL 定義、および Vax マシン記述の一部を担当した Tower、中間言語としてRTL を使用するというアイデアを提供したJack Davidson とChristopher W. Fraser 、プリプロセッサの大部分を記述した Paul Rubin など、貢献した他の人々の名前も挙げています。 [ 19 ] Peter H. Salusによって「最初のフリー ソフトウェアのヒット」と評されたGNU コンパイラは、 Sun Microsystems が開発ツールをオペレーティングシステムから分離し、以前のバンドルよりも高い合計価格で別々に販売していた時期に登場しました。そのため、Sun の多くのユーザーがベンダーのツールではなく GCC を購入またはダウンロードするようになりました。[ 20 ]ストールマンはGNU Emacsを自身の主要プロジェクトと考えていたが、1990年までにGCCは13のコンピュータアーキテクチャをサポートし、いくつかのベンダーコンパイラを凌駕し、いくつかの企業で商用利用されていた。[ 21 ]
GCC は GPL ライセンスで提供されていたため、他の方向で作業したいプログラマ、特に C 以外の言語のインターフェースを作成するプログラマは、ソース コードを配布するという要件を含む GPL の条件を満たせば、コンパイラの独自のフォークを自由に開発することができました。しかし、複数のフォークは非効率的で扱いにくく、プロジェクトが新機能よりも安定性を優先していたため、公式の GCC プロジェクトに作業を受け入れてもらうのが難しく、多くの人にとって非常に不満でした。[ 22 ] FSF は、公式バージョンの GCC 2.x (1992 年以降開発) に追加されるものを非常に厳密に管理していたため、GCC は、Eric S. Raymondのエッセイ「大聖堂とバザール」で「大聖堂」開発モデルの 1 つの例として使用されました。
1997年、開発者グループが複数の実験的なフォークを単一のプロジェクトに統合するために、Experimental/Enhanced GNU Compiler System (EGCS)を結成しました。 [ 22 ] [ 17 ]統合の基盤は、GCC の開発スナップショット (2.7.2 付近で取得され、その後 2.8.1 リリースまで追跡) でした。統合には、g77 (Fortran)、PGCC ( P5 Pentium最適化 GCC)、[ 17 ]多くの C++ の改良、および多くの新しいアーキテクチャとオペレーティングシステムのバリアントが含まれていました。[ 23 ]
両プロジェクトは互いの変更を綿密に追跡していたが、EGCSの開発ははるかに活発であったため、FSFは公式にGCC 2.xコンパイラの開発を中止し、EGCSをGCCの公式バージョンとして承認し、1999年4月にEGCSプロジェクトをGCCのメンテナーに任命した。1999年7月にGCC 2.95がリリースされると、両プロジェクトは再び統合された。[ 24 ] [ 17 ]それ以来、GCCは運営委員会の指示の下、世界中のさまざまなプログラマグループによって維持されている。[ 25 ]
GCC 3 (2002)では、メンテナンス不足のためCHILLのフロントエンドが削除されました。 [ 26 ]
バージョン 4.0 より前の Fortran フロントエンドは でしたがg77、これはFORTRAN 77のみをサポートしていました。しかし、後にFortran 95とFortran 2003およびFortran 2008の大部分をサポートする新しいGNU Fortranフロントエンドに置き換えられました。[ 27 ] [ 28 ]
バージョン4.8以降、GCCはC++で実装されています。[ 29 ]
Cilk PlusのサポートはGCC 5 から GCC 7 まで存在していました。[ 30 ] [ 31 ]
GCC はさまざまな命令セット アーキテクチャに移植されており、フリー ソフトウェアとプロプライエタリ ソフトウェアの両方の開発ツールとして広く使用されています。GCC は、 Symbian ( gcceと呼ばれる) [ 32 ] 、 ARMベース、Power ISAベースのチップ[ 33 ]など、多くの組み込みシステムでも利用可能です。コンパイラは、PlayStation 2 [ 34 ]、PlayStation 3 の Cell SPE [ 35 ]、Dreamcast [ 36 ]などのビデオゲーム コンソールを含む、さまざまなプラットフォームをターゲットにすることができます。60を超えるプラットフォームに移植されています。[ 37 ]
バージョン16.1のリリース時点で、GCC には、C ( gcc)、C++ ( g++)、Objective-C、Objective-C++、Fortran ( gfortran)、Ada ( GNAT )、Go ( gccgo)、D ( gdc、9.1 以降)、[ 38 ] [ 39 ] Modula-2 ( gm2、13.1 以降)、[ 40 ] [ 41 ] Rust ( gccrs、15.1 以降)、COBOL ( gcobol、15.1 以降)、ALGOL 68 ( 、16.1 以降) プログラミング言語のフロントエンドが含まれておりga68、[ 6 ] OpenMPおよびOpenACC並列言語拡張機能は GCC 5.1 以降でサポートされています。[ 8 ] [ 42 ] GCC 7 より前のバージョンではJava ( gcj) もサポートされており、Java をネイティブマシンコードにコンパイルすることができました。[ 43 ]
Pascal ( gpc)、Mercury、Modula-3、VHDL ( GHDL)、PL/Iなど、多くの言語向けにサードパーティのフロントエンドが存在します。[ 6 ] Unified Parallel C用の GCC UPCコンパイラなど、追加の言語をサポートする実験的なブランチもいくつか存在します。[ 44 ] [ 45 ]
GCC 15.1 以降、C++ のデフォルトターゲットはC++ 20のスーパーセットであるgnu++20であり、GCC 15 以降、C のデフォルトターゲットはC23のスーパーセットであるgnu23であり、厳密な標準サポートも利用可能です。GCC は、 C2Y、C++23、およびC++26の実験的サポートも提供しています。[ 46 ] GCC 16.1 は 2026 年 4 月 30 日にリリースされました。[ 47 ] [ 48 ]


GCCの外部インターフェースはUnixの慣例に従っています。ユーザーは言語固有のドライバプログラム(gccC言語の場合は、g++C++の場合はなど)を呼び出します。このドライバプログラムはコマンド引数を解釈し、実際のコンパイラを呼び出し、出力に対してアセンブラを実行し、必要に応じてリンカを実行して完全な実行可能バイナリを生成します。
各言語コンパイラは、ソースコードを読み込み、機械語を出力する独立したプログラムです。内部構造はすべて共通しています。言語ごとのフロントエンドがその言語のソースコードを解析し、抽象構文木(略して「ツリー」)を生成します。
これらは必要に応じて、 GENERIC形式と呼ばれる中間エンドの入力表現に変換されます。中間エンドは、プログラムを最終形式に徐々に変換します。コンパイラの最適化と静的コード解析技術 (FORTIFY_SOURCE [ 49 ]など、バッファオーバーフローを検出しようとするコンパイラディレクティブ) がコードに適用されます。これらは、主にアーキテクチャに依存しない GIMPLE 表現とアーキテクチャに依存するRTL表現という、複数の表現に対して機能します。最後に、Jack Davidson と Chris Fraser のアルゴリズムをベースとしたアーキテクチャ固有のパターンマッチングを使用して、マシン コードが生成されます。
GCCは、Adaフロントエンドの一部を除いて、主にC言語で記述されています。ディストリビューションには、AdaとC++の標準ライブラリが含まれており、そのコードのほとんどはこれらの言語で記述されています。[ 50 ]一部のプラットフォームでは、配布パッケージには、マシン非依存のC言語とプロセッサ固有のマシンコードの組み合わせで記述された低レベルランタイムライブラリlibgccも含まれており、主にターゲットプロセッサが直接実行できない算術演算を処理するように設計されています。[ 51 ]
GCC はビルド時に多くの追加ツールを使用しますが、その多くは Unix や Linux ディストリビューションでデフォルトでインストールされています (ただし、通常 Windows インストールには含まれていません) 。これにはPerl、Flex、Bison、その他の一般的なツールが含まれます。さらに、現在ビルドするには、GMP、MPC、MPFRの 3 つの追加ライブラリが必要です。[ 52 ]
2010 年 5 月、GCC 運営委員会は、GCC のコンパイルにC++コンパイラを使用することを許可することを決定しました。 [ 53 ]コンパイラは、主に C 言語と C++ の機能のサブセットで記述されることを想定していました。特に、これは GCC の開発者がC++ のデストラクタとジェネリクス機能を使用できるようにするために決定されました。[ 54 ]
2012年8月、GCC運営委員会は、GCCが実装言語としてC++を使用するようになったと発表した。[ 55 ]これは、ソースからGCCをビルドするには、 ISO/IEC C++03規格を理解するC++コンパイラが必要であることを意味する。
2020年5月18日、GCCはISO/IEC C++03規格からISO/IEC C++11規格に移行しました(つまり、コンパイラ自体をコンパイル、ブートストラップするために必要でした。ただし、デフォルトではC++のそれ以降のバージョンをコンパイルします)。[ 56 ]

各フロントエンドは、パーサーを使用して、指定されたソースファイルの抽象構文木を生成します。構文木の抽象化により、サポートされているさまざまな言語のソースファイルを同じバックエンドで処理できます。GCC は、 Bisonで生成されたLALR パーサーを使用して開始しましたが、 2004 年に C++ 用に手書きの再帰下降パーサーに徐々に切り替え、 [ 57 ] 2006 年に C と Objective-C 用に手書きの再帰下降パーサーに切り替えました。 [ 58 ] 2021 年現在、すべてのフロントエンドは手書きの再帰下降パーサーを使用しています。
GCC 4.0 までは、プログラムのツリー表現は、ターゲットとするプロセッサから完全に独立していませんでした。ツリーの意味は言語フロントエンドによって多少異なり、フロントエンドは独自のツリーコードを提供することができました。これは、GCC 4.0 の登場とともに導入された、言語に依存しない 2 つの新しい形式のツリーである GENERIC と GIMPLE の導入によって簡素化されました。GENERIC は、GCC 3.x Java フロントエンドの中間表現に基づいており、より複雑です。GIMPLE は、さまざまな構造が複数の GIMPLE 命令に縮小された、簡略化された GENERIC です。C 、C++、およびJavaフロントエンドは、フロントエンドで GENERIC を直接生成します。他のフロントエンドは、代わりに解析後に異なる中間表現を持ち、それを GENERIC に変換します。
いずれの場合も、いわゆる「gimplifier」は、このより複雑な形式を、多数の言語やアーキテクチャに依存しないグローバル(関数スコープ)最適化の共通言語である、より単純なSSAベースのGIMPLE形式に変換します。
GENERICは、ソースコードを実行可能なバイナリにコンパイルする際の「中間処理」として使用される中間表現言語です。GIMPLEと呼ばれるサブセットは、GCCのすべてのフロントエンドで対象とされています。
GCC の中間段階では、コンパイル言語とターゲットアーキテクチャの両方から独立して、GENERIC [ 59 ]表現から始めてレジスタ転送言語(RTL)に拡張し、すべてのコード解析と最適化を実行します。GENERIC 表現には、中間段階で最適化される命令型プログラミング構造のサブセットのみが含まれます。
ソースコードを GIMPLE に変換する際、[ 60 ]複雑な式は一時変数を使用して3 アドレス コードに分割されます。この表現は、命令型プログラムの解析と最適化を簡素化するために、 Laurie J. Hendren [ 62 ]が McCAT コンパイラ[ 61 ]で提案した SIMPLE 表現に触発されたものです。
最適化はコンパイルのどの段階でも実行可能ですが、最適化の大部分はフロントエンドの構文解析と意味解析の後、バックエンドのコード生成の前に実行されます。そのため、コンパイラのこの部分は、やや自己矛盾的ではありますが、「ミドルエンド」と呼ばれるのが一般的です。
GCC の最適化の正確なセットは、開発が進むにつれてリリースごとに異なりますが、ループ最適化、ジャンプスレッド、共通部分式除去、命令スケジューリングなどの標準的なアルゴリズムが含まれています。RTL最適化は、 GIMPLEツリーに対するグローバル SSA ベースの最適化が追加されたことにより重要性が低下しています[ 63 ] 。これは、 RTL最適化の範囲がはるかに限定されており、高レベルの情報が少ないためです。
このレベルで実行される最適化には、デッドコード除去、部分冗長性除去、グローバル値番号付け、疎な条件付き定数伝播、および集約のスカラー置換が含まれます。自動ベクトル化や自動並列化などの配列依存性に基づく最適化も実行されます。プロファイル誘導型最適化も可能です。[ 64 ]
GCCプロジェクトには、libstdc++と呼ばれるC++標準ライブラリの実装が含まれており、 [ 65 ] GPLv3ライセンスの下でライセンスされていますが、ソースがGCCでビルドされている場合は、GPL互換でないアプリケーションをリンクするという例外があります。[ 66 ] GCCバージョン3以降、C++ ABIは、IntelがItanium C++ ABI用に公開したABIに基づいています。[ 67 ]
GCCの主な機能には以下のようなものがあります。
-fgnu-tm。[ 7 ] [ 72 ]
主にサポートされている(そして最もテストされている)プロセッサファミリーは、64ビットおよび32ビットARM 、64ビットおよび32ビットx86、64ビットおよびx86、64ビットPowerPCおよびSPARCです。[ 76 ]
バージョン11.1時点でのGCCのターゲットプロセッサファミリには以下が含まれます:[ 77 ]
標準リリースでサポートされている、あまり知られていないターゲットプロセッサには以下が含まれます。
FSF版とは別に維持されているGCCバージョンでは、追加のプロセッサがサポートされています。
GCJ Java コンパイラは、ネイティブマシン言語アーキテクチャまたはJava 仮想マシンのJava バイトコードのいずれかをターゲットにすることができます。[ 80 ] GCC を新しいプラットフォームに再ターゲットする場合、ブートストラップがよく使用されます。さまざまな Texas Instruments、Hewlett Packard、Sharp、および Casio のプログラマブルグラフ電卓向けに開発された GCC バージョンでは、Motorola 68000、Zilog Z80、およびその他のプロセッサもターゲットにされています。[ 81 ]
GCC はGNU General Public Licenseバージョン 3に基づいてライセンスされています。 [ 82 ] GCCランタイム例外により、プロプライエタリ プログラム (フリー ソフトウェアに加えて) を GCC ヘッダーとランタイム ライブラリでコンパイルできます。これは GCC ソース コードのライセンス条項には影響しません。[ 83 ]
しかし、この例外には制限があります。たとえば、コンパイルプロセス内で非GPL互換ソフトウェアが GCC と一緒に使用される場合、GCC が生成する伝播オブジェクトコードはすべてGPLv3に従うことが必須となります。これは、 GPLライセンスのライブラリから派生しているためです。[ 84 ]
そこで彼はVUCKの作者に手紙を書き、GNUがそれを使用できるかどうかを尋ねました。明らかに、VUCKの開発者は非協力的で、大学は自由だがコンパイラはそうではないと返答しました。
は60以上のプラットフォームに移植(つまり、動作するように変更)されており、これは他のどのコンパイラよりも多い。
例外の仕組み (...) ランタイム ライブラリと独立モジュールを組み合わせて作成されたターゲット コードの著作物を、GPLv3 の条項に違反する場合であっても、すべてのターゲット コードが適格なコンパイル プロセスによって生成された場合に限り、配布する許可があります。その後、独立モジュールのライセンスに準拠した条件で、選択した条件でそのような組み合わせを伝えることができます。(...) ただし、高レベル コードを低レベル コードに変換するプロセス中に、GPL と互換性のないソフトウェアと GCC を併用した場合、それは適格なコンパイル プロセスではありません。たとえば、GCC をプロプライエタリ プラグインと併用した場合などがこれに該当します。 (…)適格なコンパイルプロセスを使用している限り、GCCが生成するターゲットコードを取得し、「選択した条件」で配布する許可が得られます。コンパイルプロセス中にGPL非互換ソフトウェアをGCCと併用した場合、この許可を利用することはできません。GCCが生成するオブジェクトコードはすべてこれらのGPLライブラリから派生しているため、そのオブジェクトコードを配布する際にはGPLの条件に従う必要があります。GCCを使用して独自のGPL非互換ソフトウェアを開発することはできません。