見出し画像

【C言語】コンパイラが何をしているのか、ちょっとのぞいてみよう その2 プリプロセッサ

C言語のコンパイラというのは、次の4つのステップで成り立ちます。

(1)プリプロセッサ
(2)コンパイル
(3)アセンブル
(4)リンク

まとめて説明しようと思いましたが、長くなったので個別に。

まずは、プリプロセッサから。

(1)プリプロセッサ

プリプロセッサというのは、「#」で始まるプリプロセッサ命令を処理します。

「#include」で指定されたファイルを読み込み、
「#define」で指定されたマクロを展開し、
「#ifdef」の条件に合致しないコードを除去します。

プリプロセッサが出力するものはまだC言語です。
プリプロセッサの出力をファイルに保存することもできます。

例えば次のようなサンプルコードを考えてみましょう。

'#include "mem.h"

'#define TEST_DATA_LEN 10

void func();
void test_mem_cpy();

int main()
{
        func();
        return 0;
}

void func()
{
        test_mem_cpy();
}

void test_mem_cpy()
{
        char data1[TEST_DATA_LEN] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
        char data2[TEST_DATA_LEN] = {};
'#ifdef _DEBUG
        print_array("data1 ", data1, sizeof(data1));
        print_array("data2 ", data2, sizeof(data2));
'#endif
        mem_cpy(data2, data1, sizeof(data2));
'#ifdef _DEBUG
        print_array("data1 ", data1, sizeof(data1));
        print_array("data2 ", data2, sizeof(data2));
'#endif
}

いろいろややこしかったので「#」の前に「'」を付与しています。

これをプリプロセッサだけ通してみます。

cc main.c -E -o _main.c

(“-E”は、「プリプロセッサだけを実行する」というオプションです。プリプロセッサで悩んだときは、これで一目瞭然です。)

するとこうなります。

# 1 "main.c"
# 1 "<built-in>" 1
# 1 "<built-in>" 3
# 385 "<built-in>" 3
# 1 "<command line>" 1
# 1 "<built-in>" 2
# 1 "main.c" 2
# 1 "./mem.h" 1
void mem_cpy(
 char* dp,
 char* sp,
 int size
);
# 2 "main.c" 2


void func();
void test_mem_cpy();
int main()
{
 func();
 return 0;
}


void func()
{
 test_mem_cpy();
}
void test_mem_cpy()
{
 char data1[10] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
 char data2[10] = {};


 mem_cpy(data2, data1, sizeof(data2));


}

絵にしてみました。


続きはこちら。

骨休めにこちらもどうぞ。


この記事が気に入ったらサポートをしてみませんか?