①プリプロセッサ
スポンサーリンク
ソースファイルから実行ファイルが出来上がるまでにはプリプロセッサ、コンパイル、リンク、という段階を踏む。(下図)
プリプロセッサ コンパイラ {ソースファイル}→ {プリプロセス} →{コンパイル} #ifdef等の処理 オブジェクト ファイルの生成 リンカ → {リンク} → {実行ファイル} オブジェクトファ イル同士の結合
これから分かるようにまずプリプロセッサが起動される。
つまりプリプロセッサがコンパイラすら行わせないような処理が出来るということだ。
このメリットはバグがあろうが無かろうがそもそもコンパイルをしないで飛ばせる。
プリプロセッサで行える主な処理は次のものである。
ディレクティブ | 機能 |
#define | define名を定義する |
#undef | define名を解除する |
#include | インクルードする |
#if〜#elif〜#else〜#endif | 条件式の結果で分岐する |
#ifdef〜#else〜#endif | define名の定義状態で条件分岐する |
#ifndef〜#else〜#endif | define名の定義状態で条件分岐する |
#error | エラーメッセージを表示する |
#ifも感覚で使えるだろうが式の評価結果に応じてソースファイルをスキップさせる。
#include<stdio.h> main(){ int n=1; printf("test-->"); #if 0 printf("n=%d\n",n); #endif } 結果 test-->
1にしたら
#include<stdio.h> main(){ int n=1; printf("test-->"); #if 1 printf("n=%d\n",n); #endif } 結果 test-->n=1
となり#if〜#endifの間が出てくる。
もちろんコンパイル前の処理なので定数以外使えない。
#ifdefはifとdefineをつなぎ合わせたもの。
#ifndefは#ifdefの否定版。if !defineをつなぎ合わせたもの。
#undefはdefineを無くす
#errorは「コンパイラ時」にエラーメッセージを表示
#include<stdio.h> #define FALSE 0 #define TRUE 1 #if defined(TRUE)||defined(FALSE) #undef TRUE #undef FALSE typedef enum{FALSE,TRUE}BOOL; #else #error "not defined" #endif main() { BOOL flag=FALSE; printf("%s\n",flag==TRUE?"TRUE":"FALSE"); } 結果 FALSE
こんな感じだがたとえば#if defined(TRUE)||defined(FALSE)を
#if defined(2RUE)||defined(4ALSE)
とかに変えて見るとコンパイラ時に
致命的エラー F1003 priprosessa.c 11: error 指令: "not defined"
と出てくる。
また定義済みdefineといって勝手に最初っから定義されて使えるものがいくつかある。
define名 | 中身 |
__LINE__ | 参照したソースファイルの行番号 |
__FILE__ | 参照したファイルの名前 |
__DATA__ | コンパイルしたときの日付(文字列) |
__TIME__ | コンパイルしたときの時刻(文字列) |
__STDC__ | ANSI Cに準拠したコンパイラである。 |
使い道はあまりないが
#include<stdio.h> main() { printf("このファイルは%s\n",__FILE__); printf("ただいま%d行目\n",__LINE__); printf("只今の時間は%s\t%s\n",__DATE__,__TIME__); #if defined(__STDC__) puts("準拠コンパイラ"); #endif } 結果 このファイルはdefine__.c ただいま5行目 只今の時間はDec 15 2005 15:17:44
こんなことも出来る。