前回は #if ディレクティブをとりあえず使ってみました。今回は、その詳しい書式と、よく使われる例について話したいと思います。
では、今回の要点です。
では、いってみましょう。
前回、#if を使いました。しかし、第1部第70章では #ifndef というのを使っていました。定義されているかの判定はよく使われるので、それ用の命令が用意されているのです。
定義されているかの判定に使われるのは、#ifdef, #ifndef の2種類です。それぞれ、if defined(もし定義されていれば)、if not defined(もし定義されていなければ)の略です。
そして、if 文に else があるように、#if ディレクティブには #else ディレクティブがあります。
また、else if に対しては、#elif ディレクティブを使います。#elifdef などはないので、#elif defined(<名前>) とする必要があります。
まとめると、例えば次のようになるわけです。
#ifdef _WIN #define RET_CODE "\r\n" #elif defined(_MAC) #define RET_CODE "\r" #else #define RET_CODE "\n" #endif
先ず、_WIN が定義されていれば RET_CODE は "\r\n" で定義されます。そして、_WIN が定義されていないが、_MAC が定義されているときは、RET_CODE は "\r" で定義されます。そして、_WIN も _MAC も定義されていないときは、"\n" で定義されます。
#if ディレクティブの評価式で使えるのは、プログラムをコンパイルする前から値を判断できるデータだけです。#if 文の動作を考えると、当然のことといえます。例えば、マクロとか、即値(生の数値)とかがそうです。
使える演算子は、C/C++のものとほとんど変わりません。使えない演算子は new, delete, sizeof のようなものくらいです。
まとめると、例えば次のようになるわけです。
define VALUE 100 #if !(VALUE % 5 == 0 && VALUE > 0) // #error ディレクティブは、強制的にエラーを出す命令です #error VALUE must be a multiple of 5 and more than 0 #endif
先ず、マクロ VALUE を定義しています。この数が「正の5の倍数でなくてはならない」としたいと思います。
ということは、VALUE が正の5の倍数でない時にはエラーを出すようにすればいいのです。#if ディレクティブでその評価を行い、そして正の5の倍数にならないときは #error ディレクティブでエラーを出します。
このようにすれば、VALUE の初期化ミスを防ぐことができます。
#if ディレクティブは、前回やったように、デバッグ時にのみ動作するコード、またはその逆のコードを書くために使うことがよくあります。そのため、VC++ではデバッグ時には _DEBUG というマクロが自動的に定義されます。他のツールであっても、似たようなマクロが定義されているかもしれません。
実は、このマクロはプロジェクトの設定内で定義されています。第1部第70章でやったようにプロジェクトの設定を開き、「C/C++」→「一般」カテゴリ→「プリプロセッサの定義」を見てみて下さい。_DEBUG と書いてあると思います。
で、デバッグを終了し、いざ本ビルドを行うというときは、メニューの「ビルド」から、「アクティブな構成の設定」を選び、Win32 Release を選択します。もしくは、ツールバーの Win32 Debug と書いてあるコンボボックスからも選択できます。こうすると、プロジェクトの設定が変わり、_DEBUG の定義されていない状態になります。
このように、VC++ではプロジェクトの設定を数種類保存でき、簡単に切り替えられるようになっています。
#if ディレクティブを使えば、デバッグ時にしか有効にならないコードを作ることもできます。その逆もできます。
#ifdef _DEBUG void Func(int a, int b); #define NOMORE default: exit(1); #else #define Func(a, b) #define NOMORE #endif
_DEBUG が定義されていないときは、Func の呼び出しは消えて、空文になってしまいます。デバッグ時にしか呼び出せないわけです。NOMORE も同じですね。
他にも、環境によって定義を変えることもできます。上で話した RET_CODE がそうです。_WIN は Windows 環境用、_MAC は Macintosh 環境用であることを表しています。で、それ以外用のが #else 以降で定義されています。
このように、#if ディレクティブを使うと、状況に合わせた柔軟なプログラムを書けるようになるのです。
ただ、#if ディレクティブを関数の中に頻繁に書いていると、非常に読みにくくなってしまいます。やむを得ない場合でも、なるべく見づらくならないような工夫をこらすようにしましょう。
例としては、上でやったデバッグ時にしか動作しないコード(またはその逆)がそうです。Func を呼ぶたびに #if ディレクティブを使うよりも、Func が消える上のコードを書いておく方がいいですね。
では、今回の要点です。
それでは、次回まで。
Last update was done on 2001.5.28
この講座の著作権はロベールが保有しています