ご存知かと思いますがGo言語には2種類のコンパイラ、gcとgccgoが用意されています。
なぜ、2種類のコンパイラが必要なのでしょうか?それぞれのメリット・デメリットは?
今回はこの2種類のコンパイラの違いについて説明しようと思います。
gc – Go Compiler
まずは、gc(Go Compiler)のほうから説明します。
gcはC言語で記述されたコンパイラで、文法解析にyacc/bisonを利用しています。
gcは後で説明するgccgoコンパイラよりコンパイル時のスピードが速いのが大きな特徴です。
このコンパイラの一風変わっているところはハードウェアシステム毎にコンパイラのコマンド名が異なる点です。コマンド名はx86-32の場合は”8g”、x86-64は”6g”と名づけられています。
この奇妙なコマンド名についてもう少し説明をしましょう。”8g”コマンドの1桁目の”8″はハードウェアのシステムを表す識別コードで、この”8″はx86-64システムを示しています。2桁目の”g”はコマンドの種類を表す識別コードで、この”g”はGo言語コンパイラという意味です。
他のコマンドにもこのルールが適用されています。詳細は下の2つの表を参照ください。
| 識別コード(コマンドの1桁目) | システム |
|---|---|
| 6 | amd64(別名 x86-64) |
| 8 | 386(別名 x86, x86-32) |
| 5 | arm(別名 ARM) |
| 識別コード(コマンドの2桁目) | コマンドの種類 |
|---|---|
| g | Go言語コンパイラ |
| a | アセンブラ |
| c | C言語コンパイラ |
| l | リンカ |
この名前のルールはPlan 9というオペレーティングシステムに由来するものです。このPlan 9は 分散オペレーティングシステムで様々なハードウェア上で動作するためこのようにシステム別のコマンドが用意されているようです。
上の表でC言語用のコンパイラが用意されていることでお分かりのように、Go言語とC言語のプログラムをリンクすることが出来ます。
gcを動かすためにはいくつか環境変数を設定しておく必要があります。詳しくはGo言語のインストールを参照ください。
gccgo – GCC GO compiler
もう一方のgccgoはgcより少し遅れて開発が開始されました。
gccの名前が示すとおりgcc(GNU Compiler Collection)を利用したコンパイラです。gccをバックエンドに使用しているためgccでコンパイルしたC言語、C++言語プログラムとのリンクが可能です。
gccgoでコンパイルしたコードはgcでコンパイルされたものより最適化されていて若干早く動作します。
ただし現時点では下に記述した、いくつかの制限事項があります。
- ガーベージコレクションが未実装
そのため長時間動作し続けるプログラムには向きません。 - goroutinesに制限がある
goroutinesとはGo言語がサポートしている軽量通信プロセスのことです。
これがgccgoではNPTL(Native POSIX Thread Library)のスレッドとして実装されていて、スタックサイズが固定という制限があります。また一度に作成できるgoroutinesの数にも制限があります。
どちらを使えばよいか
gc、gccgoのうちどちらを使えばよいか迷ったら、現時点ではgccgoにはまだ制限が多いためgcを使うのが無難なようです。