C言語/前処理指令

ソースプログラムをコンパイルする前に、ソースプログラムに対して行われる前処理をプリプロセス( preprocess )といいます。 このプリプロセスを行なうプログラムのことをプリプロセッサ( preprocessor )と呼びます。 多くのコンパイラがプリプロセッサの機能を兼ね備えていますが、cpp(1) として単体で呼び出すことも出来る場合あります。
前処理指令( preprocessing directive )は、以下の条件を満たす前処理トークン( preprocessing tokens )のシーケンスで構成されます。
前処理指令により、ソースファイルのセクションを条件付きで処理・スキップしたり、他のソースファイルをインクルードしたり、マクロを置き換えたりすることができます。 ファイルをインクルードしたり、マクロを置き換えたりすることができます。 概念的には翻訳ユニットの翻訳前に行われるため、これらの機能は前処理と呼ばれます。 前処理ディレクティブ内の前処理トークンは、特に断りがない限り、マクロ展開の対象にはなりません。
条件付き取り込み( Conditional inclusion )を制御する式は、以下を除き、整数の定数式でなければなりません 。
識別子(キーワードと同一のものを含む)は以下のように解釈されます。
前方参照:マクロの置換(6.10.3)、ソースファイルのインクルード(6.10.2)、最大の整数型
マクロ展開と定義済み単項演算子による置換がすべて実行された後、残りのすべての識別子(キーワードと語彙的に同一のものを含む)は pp-number 0 に置換されます。したがって、未定義マクロの値は 0 となります。
ソースファイル取り込み( Source file inclusion )とは、他のソースファイルを取り込む前処理指令です。
前方参照:マクロの置き換え(6.10.3)
インクルードガードとは、複数回ヘッダーをインクルードすることを防止する方法です。 インクルードガードの記述は次のようになっている。
このヘッダーをインクルードする際、 2回目以降は「インクルードガード用の識別子」が定義されているため、 ソースコードが読み飛ばされる。
また、コンパイラによっては次のようなインクルードガードの記述もある。
マクロ置き換えとは、マクロ名を置換要素並びで置き換える前処理指令です。 マクロ置き換えには、オブジェクト形式マクロと関数形式マクロがある。
次の形式の前処理指令をオブジェクト形式マクロと呼ぶ。
defineの直後に記述してある識別子をマクロ名( object-like macro )という。 オブジェクト形式マクロ( object-like macro )は、 これ以降のマクロ名を置換要素並びで置き換える。
次の形式の前処理指令を関数形式マクロ( function-like macro )と呼ぶ。
識別子並びは省略可能で、仮引数を指定し、個々の仮引数は「,」で区切り、最後に省略記号「...」を指定してもよい。 関数形式マクロは、 これ以降のマクロ名とそれに続く「(」からそれに対応する「)」までを、 置換要素並びで置き換える(マクロ呼出し)。

実引数置換とは、関数形式マクロの実引数を識別した後行われ、実引数の中に含まれるすべてのマクロの展開後、置換要素並びの中の仮引数を対応する実引数で置き換える。 ただし、#前処理字句または##前処理字句が前にある仮引数と、##前処理字句が後に続く仮引数とは除く。 実引数置換の前に、実引数の前処理字句列を完全にマクロ置き換えする。 このとき、実引数ごとに、その前処理字句列が、現在の前処理ファイルの残りとなっているものとみなして処理する。 つまり、他の前処理字句列が存在しないかのように扱われる。
置換要素並びの中に現れる識別子__VA_ARGS__は、それが一つの仮引数であるかのように扱われなければならない。 それを、可変個数の実引数が形成する前処理字句列で置き換える。
その際、「"」文字及び「\」文字の前に、「\」文字が挿入される。

関数形式マクロの置換要素並びの中で、仮引数の直前又は直後に##前処理字句がある場合、その仮引数を対応する実引数で置き換える。
実引数置換、#演算子及び##演算子の処理、プレースマーカー前処理字句の削除を行った後、さらに置き換えるべきマクロ名があるかどうかを調べるために、ソースファイル上のその後のすべての前処理字句とともにその結果の前処理字句を再走査する。
現在置き換え中のマクロの名前を置換要素並びのこの走査中に検出した場合や入れ子になった置き換えで現在置き換え中のマクロの名前を検出した場合は、置き換えは行わない。
完全にマクロ置き換えした結果の前処理字句列は、前処理指令の形をしていたとしても、前処理指令として処理することはない。
マクロ定義の有効範囲は、そのマクロ定義から、対応する#undef指令を検出するまで又は前処理翻訳単位の最後までです。
マクロ定義を無効にするには、次のように記述する。
識別子で無効にしたいマクロ名を指定する。
行制御とは、この指令の次のソース行の行番号を指定する前処理指令です。 行制御の記述は、次の2通りがある。
この指令の次のソース行の行番号が、数字列で指定された行番号となる。 数字列は1以上2,147,483,647以下の10進整数でなければならない。
この指令は、同様に行番号を設定し、s文字列でソースファイル名を置き換える。
また、次の形式の行制御の前処理指令もある。
この形式の前処理字句列は、 マクロ置き換えで、上の2通りの形式のいずれかと一致せねばならず、 一致した形式の規則に従って処理する。
エラー指令とは、処理系に対し、指定された前処理字句の列を含む診断メッセージを出力する前処理指令です。 エラー指令の記述は次のようになっている。
前処理字句列で出力する診断メッセージを指示する。
プラグマ指令( Pragma directive )は、以下のような形式をしています。

空指令とは、何の効果もない前処理指令です。 空指令の記述は次のようになっている。

この節は書きかけです。この節を編集してくれる方を心からお待ちしています。
事前定義済みマクロ定数がある。
以下のサブクラスに記載されている定義済みマクロの値は、翻訳単位全体で一定です(ただし、__FILE__ と __LINE__ を除く)。
これらのマクロ名および定義された識別子は、#define または #undef 前処理指令の対象になってはなりません。その他の定義済みマクロ名は、先頭にアンダースコアを置き、その後に大文字または2つ目のアンダースコアを置きます。
実装では、マクロ __cplusplus を事前に定義してはならず、また、標準のヘッダーでも定義してはならない。
以下のマクロ名は、実装によって定義されるものとする。
以下のマクロ名は、実装によって条件付きで定義されています。
以下のマクロ名は、実装によって条件付きで定義されます。
__STDC_NO_COMPLEX__ を定義する実装は、 __STDC_IEC_559_COMPLEX__ を定義してはならない。
※ __DATE__と__TIME__はそれを使わなければ絶対に解決できない課題を解決するためにのみ使うべきであり、それ以外の場合に安易に使うべきではない。特に、バージョン値の代用としての使用は不適切です。
プラグマ演算子は、指定した文字列リテラルを文字列解除し、その結果をプラグマ指令の中の前処理字句列として実行する。 つまり、次の形式の指令は、その次の形式でも表現できる。