3秒でわかる
人が書いたソースコードを機械語などの実行できる形へ翻訳する工程。文法の誤りを動かす前にまとめて洗い出せる点が大きな利点になります。
もう少し詳しく
どういうものか
コンパイルは、人が読める文法で書いたソースコードを、コンピュータが実行できる形式へ機械的に翻訳する工程を指す。C や Go は CPU が直接実行する機械語まで落とし、Java は仮想マシン用の中間コード (バイトコード) まで落とす。翻訳を担うプログラムがコンパイラで、内部では構文解析、型検査、最適化を順に行っている。
なぜ必要か
CPU が理解できるのは数値の命令列だけで、for や printf という文字の並びそのものには何の意味もない。どこかで機械語へ変換しなければプログラムは動かない。さらに変換の途中で型の食い違いや未定義の変数を検出できるので、動かす前に誤りをまとめて潰せる。実行して初めて落ちるインタプリタ型の言語と比べたときの、いちばん大きな違いがここにある。
具体例
C ではソースを渡すと実行ファイルができ、それを起動して初めて出力が出る。
gcc hello.c -o hello
./helloJava はバイトコードを挟む二段構えになる。
javac Hello.java # Hello.class (バイトコード) ができる
java Hello # JVM がバイトコードを実行するつまずきやすいところ
エラーの読み方でつまずく人が多い。コンパイルエラーは「翻訳できなかった」であって、プログラムが動いた結果失敗したわけではない。表示される行番号も原因の場所とは限らず、コンパイラが異常に気づいた場所を指す。セミコロンや閉じ括弧の抜けは、示された行の一つ手前を疑うと早い。もう一つ、ソースを直しただけでは実行ファイルは変わらない。直したあとにコンパイルし直さないと古い実行ファイルが動き続け、「直したのに変わらない」と悩むことになる。
似た用語との違い
| 用語 | 変換のタイミング | 代表的な言語や処理系 |
|---|---|---|
| コンパイル | 実行前にまとめて翻訳 | C, Go, Rust |
| インタプリタ | 実行しながら少しずつ解釈 | Python, Ruby |
| JIT | 実行中に、よく通る箇所だけ翻訳 | JVM, V8 |
ビルドと混同されやすいが、ビルドはコンパイルに加えてリンクや設定ファイルのコピーまで含んだ作業全体を指す。コンパイルはビルドの一工程にあたる。
覚え方
コンパイルは翻訳、実行は上演にあたる。台本を訳し終えるまで幕は上がらないし、訳した台本を差し替えなければ舞台の中身も変わらない。ソースを直したあとに必ずコンパイルをやり直す理由がこれになる。エラーが出たときも、翻訳の段階で止まったのか、上演の途中で転んだのかを最初に切り分ける。前者ならコンパイラの出力を、後者なら入力値や実行時の状態を見る。