C++ プリプロセッサ
プリプロセッサは、実際のコンパイル前に実行すべき前処理をコンパイラに指示するディレクティブです。
すべてのプリプロセッサディレクティブはハッシュ記号(#)で始まり、プリプロセッサディレクティブの前には空白文字のみが置かれます。プリプロセッサディレクティブは C++ の文ではないため、セミコロン(;)で終わりません。
これまで見てきたように、これまでのすべての例には#includeディレクティブが含まれています。このマクロはヘッダーファイルをソースファイルにインクルードするために使われます。
C++ は、#include、#define、#if、#else、#line など、多くのプリプロセッサディレクティブもサポートしています。これらの重要なディレクティブを見てみましょう。
#define プリプロセッサ
#define プリプロセッサディレクティブは、記号定数を作成するために使用されます。この記号定数は通常宏マクロと呼ばれ、ディレクティブの一般的な形式は次のとおりです:
#define macro-name replacement-text
このコード行がファイル内に現れると、そのファイル内で後続に現れるすべてのマクロは、プログラムのコンパイル前に replacement-text に置き換えられます。例:
では、このコードをテストして、プリプロセスの結果を確認してみましょう。ソースコードファイルがすでに存在すると仮定し、次に -E オプションを使用してコンパイルし、結果を test.p にリダイレクトします。test.p ファイルを確認すると、大量の情報が含まれており、ファイルの下部の値が次のように変更されていることがわかります:
$ gcc -E test.cpp > test.p
...
int main ()
{
cout << "Value of PI :" << 3.14159 << endl;
return 0;
}
パラメータ付きマクロ
#define を使用して、次のようにパラメータ付きマクロを定義できます:
上記のコードがコンパイルおよび実行されると、次の結果が生成されます:
较小的值为:30
条件付きコンパイル
プログラムのソースコードの一部を選択的にコンパイルするために使用できるディレクティブがいくつかあります。このプロセスは条件付きコンパイルと呼ばれます。
条件付きプリプロセッサの構造は、if 選択構造と非常によく似ています。次のプリプロセッサコードを見てください:
#ifdef NULL #define NULL 0 #endif
デバッグ時のみコンパイルすることができます。デバッグスイッチは、次のようにマクロを使用して実装できます:
#ifdef DEBUG cerr <<"Variable x = " << x << endl; #endif
ディレクティブ #ifdef DEBUG の前に記号定数 DEBUG が定義されている場合、プログラム内のcerr文がコンパイルされます。#if 0 文を使用して、プログラムの一部をコメントアウトできます。次のようにします:
#if 0 不进行编译的代码 #endif
次の例を試してみましょう:
例
上記のコードがコンパイルおよび実行されると、次の結果が生成されます:
Trace: Inside main function The minimum is 30 Trace: Coming out of main function
# および ## 演算子
# および ## プリプロセッサ演算子は、C++ と ANSI/ISO C の両方で使用できます。# 演算子は replacement-text トークンを引用符で囲まれた文字列に変換します。
次のマクロ定義を見てください:
例
上記のコードがコンパイルおよび実行されると、次の結果が生成されます:
HELLO C++
どのように機能するか見てみましょう。理解しやすいように、C++ プリプロセッサは次の行を:
cout << MKSTR(HELLO C++) << endl;
次のように変換します:
cout << "HELLO C++" << endl;
## 演算子は2つのトークンを連結するために使用されます。次に例を示します:
#define CONCAT( x, y ) x ## y
CONCAT がプログラム内に現れると、そのパラメータが連結され、マクロを置き換えるために使用されます。例えば、プログラム内の CONCAT(HELLO, C++) は "HELLO C++" に置き換えられます。次の例のとおりです。
例
上記のコードがコンパイルおよび実行されると、次の結果が生成されます:
100
どのように機能するか見てみましょう。理解しやすいように、C++ プリプロセッサは次の行を:
cout << concat(x, y);
次のように変換します:
cout << xy;
C++ の定義済みマクロ
C++ には、次の表に示すいくつかの定義済みマクロがあります:
| 宏 | 説明 |
|---|---|
| __LINE__ | これは、プログラムのコンパイル時に現在の行番号を含めます。 |
| __FILE__ | これは、プログラムのコンパイル時に現在のファイル名を含めます。 |
| __DATE__ | これは、ソースファイルをオブジェクトコードに変換した日付を表す month/day/year 形式の文字列を含めます。 |
| __TIME__ | これは、プログラムがコンパイルされた時刻を表す hour:minute:second 形式の文字列を含めます。 |
上記のマクロの例を見てみましょう:
例
上記のコードがコンパイルおよび実行されると、次の結果が生成されます:
Value of __LINE__ : 6 Value of __FILE__ : test.cpp Value of __DATE__ : Feb 28 2011 Value of __TIME__ : 18:52:48その他の拡張