GNU Compiler Collection (GCC) について
GNU Compiler Collection(GCC)は、
GNUプロジェクトが開発している
コンパイラ群です。略称はGCC(ジーシーシー)で、GNUツールチェーンの中核をなす重要な構成要素となっています。
概要
GCCは、C、
C++、Objective-C、Objective-
C++、Fortran、
Ada、Go、Dなど、幅広いプログラミング言語に対応した
コンパイラと、それらの言語のライブラリを含んでいます。バージョン7以前には
Javaもサポートされていました。当初はGNU C Compilerとして開発されましたが、設計段階から
多言語対応を想定しており、現在ではGNU Compiler Collectionを意味するようになりました。
現在でもGNU C Compilerの意味で「GCC」と呼ぶことが多く、C
コンパイラの実行ファイル名も「gcc」です。
C++コンパイラは「g++」、
Javaコンパイラは「gcj」、
Adaコンパイラは「gnat」と呼ばれています。
C
コンパイラとしてのGCCは、ANSI規格にほぼ準拠しており、登場当初はANSI規格に適合していない
コンパイラが多かったため、GCCがANSI規格を普及させる役割を果たしました。GCC自身はK&Rの範囲内の
C言語で記述されていたため、OS付属の
コンパイラでコンパイルが可能でした。しかし、GNU拡張という独自の仕様も存在し、GCCでコンパイルできるものがANSI規格準拠の
コンパイラでコンパイルできるとは限りません。
歴史
GCCは1985年、
マサチューセッツ工科大学(MIT)のリチャード・ストールマン氏によって、既存の
コンパイラを拡張する形で開発が開始されました。当初は
Pascalの方言であるPastelで記述されていましたが、その後ストールマン氏とLeonard H. Tower, Jr.氏によって
C言語で書き直され、1987年に
GNUプロジェクトの一つとして公開されました。
2012年にはLawrence Crowl氏とDiego Novillo氏によって
C++で書き直されました。
EGCS (Experimental/Enhanced GNU Compiler System)
EGCSは、1997年に開発中のGCC 2.8をベースとして、Cygnus社のEGCS Steering Committee(後のGCC Steering Committee)によって開発された拡張版GCCです。1999年4月にはGCCと再統合され、EGCSがGCCの公式バージョンとなりました。この際、GCCはGNU Compiler Collectionの意味を持つようになり、開発主力はGCC Steering Committeeに移りました。統合後、最初のリリースは1999年7月のGCC 2.95です。
構成
GCCは、一般的な
コンパイラと同様に、フロントエンド部、最適化部、バックエンド部から構成されています。
フロントエンド部: 字句解析、構文解析などを行い、各言語に対応したものが用意されています(例:C++フロントエンド、Javaフロントエンド)。
最適化部: コードの最適化を行います。
バックエンド部: コード生成を担当します。
最適化部とバックエンド部のコード生成部は、すべての言語で共通です。そのため、GCCが対応する言語間では、生成されるコードの質や対応するCPUの種類が同じになります。フロントエンドとバックエンドの間では、中間形式としてレジスタ転送言語(RTL)が使用されます。
GCCのフロントエンドは、構文解析部生成系bisonや字句解析部生成系flexなどのツールを使って構築されており、これらのツールは単独のフリーソフトウェアとしても有用です。
GCCバージョン4以降では、中間形式にGENERICとGIMPLEが追加されました。各言語はまずGENERICに変換され、その後GIMPLEで最適化され、最後にRTLで最適化が行われます。また、CやC++のコンパイル時に、フロントエンドの構文解析や字句解析でbisonやflexを使用しなくなりました。
影響と評価
貢献:
GCCは、それ自体が有用なフリーソフトウェアであるだけでなく、OSやDOSエクステンダの構築基盤としても重要な役割を果たしています。LinuxやFreeBSDのようなフリーソフトウェアのOSは、GCCなしでは大きく異なっていたと考えられています。Linuxの創始者であるリーナス・トーバルズ氏は、GCCをGNUプロジェクトの中で最も重要なものとして挙げています。
また、多くの組み込みOSやゲーム開発環境でもGCCが採用されています。これは、GCCが幅広いプロセッサに対応しているため、クロス開発が容易になる点が評価されているからです。
現状:
一方で、最適化においては、特定のプロセッサに特化した商用コンパイラに劣る面があります。特に、科学技術演算で多用されるベクトル演算や、特定のベンチマークではその差が顕著です。これは、GCCが多様な環境への対応を優先しており、個別のプロセッサ向けの最適化に注力してこなかったことが要因の一つですが、最近では改善の試みも行われています。
批判
GCCは、GNU General Public License(GPL、特にバージョン3)との関係で問題視されることがあります。そのため、「GPLフリー」を目指して、OSの標準コンパイラをGCCから別のものに切り替える動きもあり、FreeBSDでは2012年に標準コンパイラをClang/LLVMに切り替えました。
GNU Cコンパイラの主な特徴は、ANSIやISOなどの標準規格への準拠と、独自の拡張機能です。GCC拡張機能には、多引数マクロ、複素数型、式の演算結果としての左辺値、初期化式の拡張、Cでのインライン関数定義、ネストした関数定義、ラベルに対する&演算子の適用などがあります。
これらの拡張機能は、C99などの標準Cに取り込まれたものもあります。言語機能の拡張以外にも、asm文によるインラインアセンブラ機能はユニークです。ただし、GCCのインラインアセンブラで記述したコードは最適化される可能性があるため、プログラマの意図どおりにコードが出力されない場合があることに注意が必要です。
また、GCC (G++)は、研究論文の実装例や実験的機能の実装ベースとして利用されることも多く、スタックバッファオーバーフローの脆弱性対策として知られるGCC拡張のProPoliceなどが例として挙げられます。
最適化
GCCは高度な最適化を行いますが、CPUベンダやRISCワークステーションメーカが提供するコンパイラに比べて見劣りする場合もあります。マルチアーキテクチャに対応するため、機種に依存しない最適化が中心となり、特定のCPUに特化したコンパイラに比べて不利な点があります。
GCC 4.0では、ループ最適化や自動ベクトル化などの最適化機構が大幅に見直されましたが、GCC 3.xで書かれたコードがコンパイルエラーになるなど、互換性の問題点も指摘されました。GCC 4.2ではバグ修正や最適化の改善に加え、OpenMPに対応し、GCC 4.3ではループの自動並列化によるマルチスレッド処理が可能となりました。これにより、マルチプロセッサ環境でのアプリケーション性能が向上しましたが、シングルスレッドアプリケーションでは3.x系よりも性能が劣る場合もあります。
GCC 4.5ではリンク時最適化が導入され、複数のオブジェクトファイルにまたがるプログラムに対して、より効果的な最適化が可能となりました。これは、プロシージャ間最適化やプログラム全体の最適化を改善するために不可欠な要素です。
1990年頃のGCC 1.xや2.xは、特にMC680x0系に対して商用コンパイラを凌駕する最適化品質を誇っていましたが、これは同時代の68k系商用コンパイラとの相対的な比較によるものです。1990年代後半には、インテルPentium専用の最適化を行うGCC派生版であるPGCCも存在しました。
サポートするアーキテクチャ
GCCは幅広いアーキテクチャをサポートしています。
脚注
[1] この記事で説明したProPoliceはGCCの拡張機能の一つです。
関連項目
コンパイラ
GNUプロジェクト
フリー
ソフトウェア
外部リンク
GCC, the GNU Compiler Collection - GNU Project - Free Software Foundation (FSF) 公式ウェブサイト (英語)
本の虫: OpenBSDのコンパイラー GCC 2.5からEGCSまでの記載もある