一覧へ

コンパイルの過程 — ソースコードから実行ファイルまで

コンパイラとインタプリタの違い、ソースコードが機械語になる過程、ビルドの過程を段階的に理解します。

入門
|
10
|
検証済み (2026-07)
コンパイルインタプリタ機械語ソースコードビルド過程
進捗0/23 (0%)

コンパイルの過程 — ソースコードから実行ファイルまで

このトピックを終えると

コンパイラとインタプリタの違いを説明できるようになり、ソースコードが機械語に変換される段階を理解し、Python、JavaScript、Cがそれぞれどのように実行されるかを知ることができます。


コンピュータはソースコードを読めない

私たちが書くコードは人間向けのテキストです。

python
print("Hello, World!")

CPUが理解するのは機械語 — 0と1で構成された命令です。

text
10110000 01001000  (mov al, 'H')
11001101 00100001  (int 21h)

ソースコードを機械語に変換する必要があります。この変換を行うプログラムがコンパイラインタプリタです。


コンパイラ vs インタプリタ

コンパイラインタプリタ
変換のタイミング実行前に全体を一度に変換実行しながら1行ずつ変換
結果実行ファイル(バイナリ)なし(即時実行)
エラー検出コンパイル時に全体のエラーを表示該当行の実行時にエラー
実行速度速い(すでに変換完了)比較的遅い
代表的な言語C、C++、Rust、GoPython、JavaScript、Ruby

たとえれば、コンパイラは本の翻訳(全体を最初に翻訳してから出版)、インタプリタは同時通訳(話している即時に翻訳)です。


コンパイルの段階 — C言語の場合

Cコードが実行ファイルになる過程:

text
ソースコード (.c)
    ↓ 前処理 (Preprocessing)
前処理されたコード
    ↓ コンパイル (Compilation)
アセンブリコード (.s)
    ↓ アセンブル (Assembly)
オブジェクトファイル (.o)
    ↓ リンク (Linking)
実行ファイル (a.out / .exe)

1. 前処理 (Preprocessing)

c
#include <stdio.h>
#define MAX 100

int main() {
    printf("Max is %d\n", MAX);
}

#includeを実際のヘッダーファイルの内容に置き換え、#defineを値に置き換えます。この段階はテキスト置換です。

2. コンパイル (Compilation)

前処理されたコードを解析してアセンブリコードに変換します。文法エラーはここで検出されます。

asm
mov    edi, OFFSET FLAT:.LC0
mov    esi, 100
call   printf

3. アセンブル (Assembly)

アセンブリコードを機械語(二進命令)に変換します。結果はオブジェクトファイル(.o)です。

4. リンク (Linking)

複数のオブジェクトファイルとライブラリを1つの実行ファイルに結合します。printfの実際の実装はC標準ライブラリにあるため、リンカがこれを接続します。

bash
# GCCがこれらのすべてのステップを一度に行う
gcc hello.c -o hello
./hello

Pythonはどのように実行されるか

Pythonはコンパイル + インタプリタのハイブリッドです。

text
ソースコード (.py)
    ↓ Pythonコンパイラ
バイトコード (.pyc)
    ↓ Python仮想マシン (PVM)
実行結果
python
# バイトコードの確認
import dis
def add(a, b):
return a + b
dis.dis(add)
# LOAD_FAST 0 (a)
# LOAD_FAST 1 (b)
# BINARY_ADD
# RETURN_VALUE

バイトコードは機械語ではありません。Python仮想マシン(PVM)と呼ばれるインタプリタがバイトコードを1行ずつ実行します。CのようにCPUが直接実行するよりも遅いですが、OSに関係なく実行できます。

__pycache__/フォルダに.pycファイルが生成されることがあります。これはバイトコードキャッシュです。ソースが変更されない場合、再コンパイルせずにキャッシュを使用します。


JavaScriptはどのように実行されるか

JavaScriptエンジン(V8、SpiderMonkey)はJIT(Just-In-Time)コンパイルを使用します。

text
ソースコード (.js)
    ↓ パース
AST(抽象構文木)
    ↓ インタプリタ
バイトコード実行(遅い)
    ↓ JITコンパイラ(頻繁に実行されるコードを検出)
機械語に変換(速い)

最初はインタプリタで迅速に実行を開始し、「この関数が1,000回呼び出された」と検出すると、その部分だけを機械語にコンパイルします。実行中にコンパイルするため「Just-In-Time」と呼ばれます。


Java — コンパイルとインタプリトの正統なハイブリッド

JavaはPythonに似ていますが、少し複雑です。

text
ソースコード (.java)
    ↓ javac(コンパイル)
バイトコード (.class)
    ↓ JVM(Java Virtual Machine)
    ├── インタプリタ(最初)
    └── JITコンパイラ(頻繁に実行されるコード)
    ↓
機械語実行
java
// Hello.java
public class Hello {
    public static void main(String[] args) {
        System.out.println("Hello, World!");
    }
}
bash
javac Hello.java # バイトコード (.class) を生成
java Hello # JVMがバイトコードを実行

「Write once, run anywhere」 — Javaバイトコードは、JVMがある場所ならどこでも実行されます。Windowsでコンパイルされた.classファイルがLinuxのJVMでも動作します。


静的型 vs 動的型

コンパイルと密接に関連する概念が型システムです。

c
// C: 静的型 — コンパイル時に型を確認
int x = 42;
x = "hello";  // コンパイルエラー!
python
# Python: 動的型 — 実行時に型を確認
x = 42
x = "hello" # OK — 実行中に型が変更される
静的型動的型
型の確認タイミングコンパイル時実行時
エラー検出実行前実行中
型の明示必須 (int x)不要 (x = 42)
実行速度速い比較的遅い
代表的な言語C、Java、TypeScriptPython、JavaScript、Ruby

実践における意味

text
なぜPythonはCよりも遅いのか?
→ C: CPUが機械語を直接実行
→ Python: 仮想マシンがバイトコードを1行ずつ解釈して実行

なぜTypeScriptを使うのか?
→ JavaScriptに静的型を追加 → 実行前にエラーを検出
→ TypeScript → (tscコンパイル) → JavaScript → (V8実行)

なぜDockerイメージがOSごとに異なるのか?
→ コンパイルされたバイナリはCPUアーキテクチャ(x86、ARM)に依存
→ macOS用のバイナリはLinuxで実行できない

核心のまとめ

概念まとめ
コンパイラ全体のソースを事前に機械語に変換。高速な実行
インタプリタ1行ずつ解釈して実行。迅速な開発
バイトコード中間形態。仮想マシンが実行(Python、Java)
JIT実行中に頻繁に使う部分だけを機械語にコンパイル(JavaScript)
静的型コンパイル時に型を確認(C、TypeScript)
動的型実行時に型を確認(Python、JavaScript)

ビルドツールとトランスパイラ

現代の開発では、「純粋な」コンパイル/インタプリト以外にも、さまざまな変換ツールがあります。

text
TypeScript → (tsc) → JavaScript → (V8) → 実行
JSX/React  → (Babel) → JavaScript → (V8) → 実行
Sass/SCSS  → (sass) → CSS → ブラウザレンダリング

トランスパイラは同じレベルの言語に変換します。コンパイラが高レベル→低レベルの変換であるのに対し、トランスパイラは高レベル→高レベルの変換です。TypeScript→JavaScript、ES6→ES5が代表的です。


「Pythonはインタプリタ言語」は半分だけ正しい — バイトコードにコンパイルした後にインタプリトします。「JavaScriptはインタプリタ言語」も半分だけ正しい — V8はJITコンパイルを行います。現代の言語は、コンパイルとインタプリトを組み合わせて、開発の容易さと実行パフォーマンスの両方を追求しています。

💬 質問・コメント

0件のコメント

ログインせずに投稿できます。ゲスト投稿は投稿者自身で編集・削除できません。

0/2000

読み込み中...