cppreference.com -> プリプロセッサ命令 -> Details

プリプロセッサ命令


#,##

# , ## 演算子は#defineマクロと一緒に使用される。 # を使用することで引数を文字列として扱うことができる。サンプル:

    #define to_string( s ) # s

以下のようなコードがあったとする:

    cout << to_string( Hello World! ) << endl;

コンパイル時には以下のようにダブルクオートされた文字列として展開される。

    cout << "Hello World!" << endl;

## は前後の文字を結合するのに使用する。サンプル:

    #define concatenate( x, y ) x ## y
    ...
    int xy = 10;
    ...

以下のようなコードがある:

    cout << concatenate( x, y ) << endl;

コンパイル時には以下のように展開される:

    cout << xy << endl;

標準出力には'10'と表示される。


#define

文法:

  #define マクロ名 置き換える文字列

#defineコマンドはそのファイル中の文字列を置換するのに使用される。#defineを使用すると、ファイル中のマクロ名 という文字列が置き換える文字列 に置換される。置換はファイルの最後に達するまで行われる。以下のサンプルはC言語でよく用いられたテクニックである:

    #define TRUE 1
    #define FALSE 0
    ...
    int done = 0;
    while( done != TRUE ) {
       ...
    }

#defineコマンドのもう一つの機能として、引数を持たせて疑似関数のように使用することができる:

    #define absolute_value( x ) ( ((x) < 0) ? -(x) : (x) )
    ...
    int x = -1;
    while( absolute_value( x ) ) {
       ...
    }

複雑な使用法をされる場合には置き換え後のマクロ定義内の変数はかっこでくくる方が良い。上記の例であれば、変数"x"は常にかっこでひとくくりにされる。こうすれば、0と比較したり-1を掛ける前に"x"全体が評価される。xに式を入れても優先順位の問題で予定通りに解釈されないというのを防ぐことができる。また、マクロ全体も同様にかっこでくくる方が良い。他のコードに侵されるのを防ぐことができる。このような注意を怠ると、コンパイラは意図通りにはコードを解釈してくれなくなるだろう。


#error

文法:

  #error メッセージ

#errorコマンドはコンパイラの処理を止める。コンパイラが#errorコマンドを読み込んだら、行番号と理由としてメッセージ を表示する。このコマンドはデバッグ用にもっとも使用される。


#if, #ifdef, #ifndef, #else, #elif, #endif

これらのコマンドはコンパイラに対する論理的な処理を提供する。 ファイルがコンパイルされる時に、これらのコマンドを使用して特定の行を処理させないようにしたり、処理させるようにすることができる。

    #if 式

もし の値がtrueならばそのコマンドがある行以下がコンパイルの対象になる。

    #ifdef マクロ

もしもマクロ が#define命令を使って定義されていた場合には、そのコマンドがある行以下がコンパイルの対象になる。

    #ifndef マクロ

もしもマクロ が#define命令を使って定義されていなかったた場合には、そのコマンドがある行以下がコンパイルの対象になる。

補足: #elifは"elseif"略した言葉のように見えるだろう。実際期待通りに動作する。また、#ifの中で"defined", "!defined"と書くこともできる。

以下のコードはこれらのコマンドのサンプルである:

    #ifdef DEBUG
      cout << "テストバージョン, i=" << i << endl;
    #else
      cout << "製品バージョン!" << endl;
    #endif

2番目のサンプルはデバッグで無数の"cout"をコードに埋め込むよりはシンプルだと感じるだろう。


#include

文法:

  #include <ファイル名>
  #include "ファイル名"

このコマンドはファイルを現在の位置に挿入する。この2つの文法の大きな違いはファイル名 で示されるファイルをコンパイラがどこから検索するかというところにある。< >でくくった場合には通常、標準ライブラリのディレクトリを検索し、" "でくくった場合にはカレントディレクトリから検索を行う。


#line

文法:

  #line 行番号 "ファイル名"

#lineコマンドは__LINE__マクロと__FILE__マクロの値を変更するために使用する。 ファイル名はオプションである。__LINE__マクロと__FILE__マクロは現在コンパイラが処理中のファイル名と行番号を表す。以下のように

    #line 10 "main.cpp"

とすることで現在の行番号を10に、現在のファイル名を"main.cpp"にする。


#pragma

#pragmaコマンドはプログラマがコンパイラに命令を出す時に使用する。#コマンドの実装の詳細はコンパイラごとに異なる。プログラムの実行をトレースするオプションなどもある。


#undef

#undefコマンドは前に#defineで定義したマクロを解除するために使用する。


定義済みマクロ

文法:

  __LINE__
  __FILE__
  __DATE__
  __TIME__
  _cplusplus
  __STDC__

以下のマクロはコンパイラによって違う可能性はあるが、多くの場合は動作するだろう: