読者です 読者をやめる 読者になる 読者になる

電脳ミツバチのコンピュータ広報室

銀座の屋上菜園を耕しています。コンピュータ畑も耕します。

①プリプロセッサ

スポンサーリンク

ソースファイルから実行ファイルが出来上がるまでにはプリプロセッサコンパイル、リンク、という段階を踏む。(下図)

          プリプロセッサ    コンパイラ
{ソースファイル}→ {プリプロセス} →{コンパイル}
         #ifdef等の処理   オブジェクト
                  ファイルの生成


     リンカ
 →   {リンク}   →    {実行ファイル}
  オブジェクトファ
  イル同士の結合
	

これから分かるようにまずプリプロセッサが起動される。
つまりプリプロセッサコンパイラすら行わせないような処理が出来るということだ。
このメリットはバグがあろうが無かろうがそもそもコンパイルをしないで飛ばせる。
プリプロセッサで行える主な処理は次のものである。

ディレクティブ機能
#definedefine名を定義する
#undefdefine名を解除する
#includeインクルードする
#if〜#elif〜#else〜#endif条件式の結果で分岐する
#ifdef〜#else〜#endifdefine名の定義状態で条件分岐する
#ifndef〜#else〜#endifdefine名の定義状態で条件分岐する
#errorエラーメッセージを表示する
#includeと#defineは見慣れているので省略。

#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

こんなことも出来る。