GNU Compiler Collection (グヌーコンパイラコレクション)は、GNU のコンパイラ 群である。略称は「GCC (ジーシーシー)」。GNUツールチェーン の中核となる構成要素(コンポーネント)にもなっている。
概説 最新標準パッケージには C 、C++ 、Objective-C 、Objective-C++ 、Fortran 、Ada 、Go 、D のコンパイラ並びにこれらのライブラリ が含まれている。[2] バージョン7以前では、Java もサポートされていた。[3]
当初はCコンパイラ として開発し、GCCは GNU C Compiler を意味していた。しかし、もともと多言語 を想定して設計しており、 GNU C Compiler と呼ばれていたときでも多くの言語に対応していた。現在でも GNU C Compiler の意味で「GCC」と呼ぶことも多い。ちなみに GNU C Compiler の実行ファイルの名称もgcc
である。なお、GNU C++コンパイラをG++ 、GNU JavaコンパイラをGCJ 、GNU AdaコンパイラをGNAT と呼ぶ。
CコンパイラとしてのGCCは、ANSI規格 (ANSI X3.159-1989) にほぼ適合するC言語コンパイラ処理系 であった。登場当初の時点では、オペレーティングシステム (OS) 標準に付属するCコンパイラがANSI規格に適合していない部分が多いものがあった。そのため、GCCはANSI規格を広める役割を果たした。GCC自身はK&R の範囲内のC言語で記述していたので、OS 付属のコンパイラでコンパイルできた。ただし、GNU拡張という独自の仕様もあり、GCCでコンパイルできるものがANSI適合コンパイラでコンパイルできるとは限らない。
歴史 1985年、当時マサチューセッツ工科大学 (MIT) の研究者であったリチャード・ストールマン によって、既成のコンパイラを拡張する形で開発が始められた。当初コンパイラはPastel(英語版 ) というPascal の方言によって書かれていた。その後ストールマンとLeonard H. Tower, Jr.によってC言語で書き直され、GNUプロジェクト の一つとして1987年に公開された。さらに2012年にはLawrence CrowlとDiego NovilloによってC++で書き直された。
EGCS EGCS (エッグズ[4] 、Experimental/Enhanced GNU Compiler System) は、1997年に当時開発中のGCC 2.8をベースとしてCygnus社のEGCS Steering Committee(後のGCC Steering Committee)により開発された拡張版GCCである。1999年4月、GCCと再統合されてEGCSがGCCの公式バージョンとなり、GCCの開発主力はGCC Steering Committeeに委ねられた。また、この時点でGCCはGNU Compiler Collectionの意味となった[5] 。統合後初めてリリースされたバージョンは、1999年7月のGCC 2.95である。
GCCの主なバージョン[6] 日付 バージョン 内容 1999年7月31日 2.95 1999年4月のGCC/EGCS再統合以来のGCCの最初のリリースであり、ほぼ1年分の新しい開発とバグ修正が含まれている。 2001年6月18日 3.0 2002年5月15日 3.1 ほとんどのELFプラットフォームの既定のデバッグ形式がDWARF2に。 2002年8月14日 3.2 2003年5月13日 3.3 2004年4月18日 3.4 GCCの実装がK&RからC89に変更。新しいプロシージャ間最適化を実装。 2005年4月20日 4.0.0 tree ssaブランチをマージ。既存のRTL表現よりも高レベルの中間表現に基づく完全に新しい最適化フレームワークを採用。 2007年5月13日 4.2.0 OpenMP 2.5サポート 2008年3月5日 4.3.0 Intel Core 2とAMD Geodeプロセッサのサポートを強化 2009年4月21日 4.4.0 大量の新機能を含んだメジャーリリースバージョン。Graphiteブランチが統合され、新しいループ最適化のフレームワークを採用。 2010年4月14日 4.5.0 C++0xの実験的サポート (ラムダ式、型変換演算子、raw string)。新しいリンク時最適化(LTO)のフレームワークを採用。 2011年3月25日 4.6.0 Intel Sandy Bridgeプロセッサに対応 (AVX拡張命令セットも対応) 2012年3月22日 4.7.0 プロシージャ間最適化(IPO)の改善 2013年3月22日 4.8.0 GCCの実装がCからC++98に変更された。アドレスサニタイザ、スレッドサニタイザが追加。新しいローカルレジスタアロケータ(LRA)が実装。DWARF4が既定のデバッグ形式に。 2014年4月22日 4.9.0 C++14の機能追加、OpenMP 4.0対応。未定義動作サニタイザが追加。リンク時最適化の改善。 2015年4月22日 5.1 CのデフォルトがC11のGNU拡張に。未定義動作サニタイザの新しいオプション。ポインタ境界チェッカー。 2016年4月27日 6.1 C++14がデフォルトに。OpenMP 4.5をフルサポート。配列境界チェッカー。 2017年5月2日 7.1 C++17の実験的サポート。アドレスサニタイザの新しいオプション。 2018年5月2日 8.1 C17をサポート。エラーメッセージを改善。 2019年5月3日 9.1 2020年5月7日 10.1 C++14とC++17の間のABIの非互換性が修正。 2021年4月27日 11.1 GCCの実装がC++11に変更された。C++17がデフォルトに。DWARF5が既定のデバッグ形式に。 2021年5月14日 8.5 2021年6月1日 9.4 2021年6月28日 11.2 2022年4月21日 11.3 2022年5月6日 12.1 シャドーコールスタックサニタイザがAArch64に追加。 2022年5月9日 9.5 2022年6月28日 10.4 2022年8月19日 12.2 2023年4月26日 13.1 2023年5月8日 12.3 AMD Zen 4プロセッサーのサポート。(-march=znver4)
構成 GCCは通常のコンパイラと同様にフロントエンド 部、最適化部、バックエンド 部から構成される。
フロントエンド部は字句解析 、構文解析 などを行い、対応言語ごとに用意されている。たとえばC++フロントエンド、Javaフロントエンドなどがある。
バックエンド部のコード生成 部(コードジェネレータ)、および最適化 部(オプティマイザ)は全言語で共通である。したがってGCCの対応の言語同士の間では、生成コードの質や対応するCPUの種類は原理的に同じになる。なお、フロントエンドおよびバックエンドの間でやりとりされる中間形式としてレジスタ転送言語(英語版 ) (RTL) が使用される。
CコンパイラとしてのGCCの開発のために開発された構文解析部生成系bison やフリーな字句解析部生成系flex といったプログラムを使用してGNU Cコンパイラその他の各種フロントエンドは構築されている。これらは単独のフリーソフトウェアとしても有用なものである。
GCCはバージョン4から中間形式が2つ追加された。まず、各言語は通常フロントエンド言語の木構造 を保持した共通中間形式のGENERICに変換されその後GIMPLEという中間形式で木の最適化SSA をおこなってからRTLの最適化がおこなわれる。また、CやC++のコンパイル時にフロントエンドの構文解析、字句解析においてbisonやflexを使用しなくなった。
影響と評価 貢献 GCCはそれ自身が有用なフリーソフトウェア だが、OSやDOSエクステンダ (DJGPP、EMXなど)を構築するための基盤ツールとしても非常に有用であり、商用・非商用を問わず多くの環境で標準的なCコンパイラとして採用されている。特にLinux やFreeBSD など、フリーソフトウェアとしてのOSは、もしGCCが存在しなかったならば大きく違ったものになっていたであろうと言われている。実際Linuxの生みの親であるリーナス・トーバルズ はGCCをGNUプロジェクトの中で最も重要なものとして挙げている[7] 。
また、多くの組み込みOS や、ゲームの開発環境でもGCCを採用している場合も多い。これは、クロス開発を容易なものとするGCCの広範なプロセッサへの対応が評価されていることによる。
その一方で、現状では生成コードの最適化において、特定のプロセッサへの最適化を図る商用コンパイラに水をあけられているのが実情である。特に科学技術演算で多用されるベクトル演算機構への対応や、特定のベンチマークなどでは顕著であった。これは多様な環境に対応することを第一とし、個別のプロセッサ向けの最適化を追求してこなかったことも大きな要因であったが、最近ではこれを改善するための試みも始められている。(最適化を参照)
批判 GCCを巡っては、GNU General Public License (特にバージョン3)との関係が問題視される場合がある。実際「GPLフリー」を目指して、OS(あるいはプラットフォーム)の標準コンパイラをGCCから別のものに切り替える動きも有り、一例としてFreeBSD では、2012年 に標準コンパイラをGCCからClang /LLVM に切り替えた[8] 。
GNU Cコンパイラ拡張 GNU C コンパイラの特徴のひとつは、前述のようにANSIあるいはISO等の標準への準拠である。もうひとつの特徴は独自の拡張機能である。このような拡張を「GCC拡張機能」とよぶ。GCC拡張機能は数多いが、多引数マクロ 、基本型としての複素数 型、式の演算結果としての左辺値、初期化式の拡張、Cでのインライン関数定義、ネスト した関数定義、ラベルに対する&演算子 の適用などがある。
このような拡張は、C99 における標準Cの拡張として逆に取り込まれたものも多い。
言語機能の拡張のほかに、標準外機能としてasm文によるインラインアセンブラ の機能はユニークである。ただし、GCCにおいてはこのインラインアセンブラ機能を利用して記述したコードに対しても最適化が行われる(プログラマが意図してアセンブリ言語 を用いて書いたとしても、その通りのコードが出力されない可能性がある)点に注意が必要である。
その他、研究論文の発表における実装例のベースとして、あるいは実験的機能実装のベースとしてGCC (G++)が使われることも多い。そのような拡張の最近の例としては、スタックバッファオーバーフロー に関する脆弱性の回避のためのGCC拡張ProPoliceなどがある。[1]
最適化 GCCは高度な最適化を行うが、CPUベンダやRISCワークステーションメーカが提供するコンパイラと比べると見劣りする場合もある。マルチアーキテクチャゆえに、機種依存しない最適化が中心となるため、特定の CPU に特化した専用コンパイラと比べてやや不利な立場といえる。
2005年4月にリリースされたGCC4.0はループ 最適化の改善や自動ベクトル化 など最適化機構が大幅に見直されている反面、GCC3.x で書かれたコードがコンパイルエラーになることがあり、互換性 において若干の問題点がある。GCC4.2ではバグ修正、最適化の改善に加え、新機能としてC 、C++ 、Fortran でOpenMP に対応し、さらにGCC4.3ではループの自動並列化 によるマルチスレッド 処理が可能となるなど、マルチプロセッサ環境では大幅にアプリケーションの性能を引き上げることが可能になった。ただし、マルチスレッドやベクトルプロセッサを使用しないことを前提としたシングルスレッドアプリケーションにおける最適化においては3.x系よりも一部のプログラムにおいて劣る場合もある。
2010年4月にリリースされたGCC4.5ではリンク時最適化が導入され、複数のオブジェクトファイルにまたがるプログラムに対してより効果的に最適化ができるようになった。なおリンク時最適化とは単にリンク時に行う最適化を意味し、プロシージャ間最適化(英語版 ) やプログラム全体最適化を改善する上で求められるようになった[9] 。
1990年頃のGCC1.xや2.xは、特にMC680x0系に対して商用コンパイラを凌駕する最適化品質を誇っていたとされる[10] 。ただし、これは同時代の68k系商用コンパイラとの相対的な比較・評価であり絶対的な指標によるものではない。
また1990年代後半のPGCCはインテル Pentium 専用の最適化を行うGCC(正確にはegcs)の派生であり、通常版と比べてPentium CPU上でより効率良く動作するコードを生成する[11] 。
サポートするアーキテクチャ
脚注 関連項目 外部リンク