プリプロセッサ
From Wikipedia, the free encyclopedia
プログラミング言語のプリプロセッサ
処理内容
以下のようなものがある(実際には、各言語あるいはプリプロセッサ次第であって、以下に挙げられているものは全て任意の例である)。
- ファイルの読み込み (including)
- マクロの展開(シンボルを、あらかじめ定義された規則に従って置換する)
- コンパイル条件によるソースコードの部分的選択
- コメントの削除
環境
注意点
プリプロセッサを通すことを前提に記述されたプログラムは、コンパイラのあずかりしらない内容を含んでいることになる。このことは、たとえばマクロの定義と同じ文字列が(意図せず)全て変換されてしまったり、定数の型をチェックできなかったりと、問題の火種をはらんでいる。そのため、プリプロセッサを用いる場合には注意が必要である。
このような名前衝突の問題をさけるための対策として、少なくともユーザー定義のマクロの識別子は大文字だけで記述し、それ以外の識別子は小文字をまぜる(例:NAME→name, Name)という慣習があり、マクロ以外は全部大文字で書くべきではないとされる。[1][2][3]。
例:プリプロセッサと同じく全て大文字で定数を定義してしまった場合
// define0.h
const int ARRAY_LENGTH = 1000;
// define1.h
#define ARRAY_LENGTH 50
// source1.cpp
#include "define0.h"
#include "define1.h"
int global_variable1[ARRAY_LENGTH]; // 警告なしで要素数が50になってしまう。
// source2.cpp
#include "define0.h"
int global_variable2[ARRAY_LENGTH]; // source1と異なり、要素数が1000になる。
C言語の規格自体は、マクロと非マクロの識別子に関して、大文字・小文字の使い分けを規定してはおらずISO/IEC 9899およびJIS X3010の§6.10.3にて例示されたマクロには、すべて大文字のものもあれば、すべて小文字のものもある。しかし、これらは危険性が認知される前の名残とされる。[2]後発のC99規格やC11規格でもbool, true, false, offsetof(), noreturnなど[4][5][6]、依然として小文字のマクロが標準仕様として追加導入されていたが、これらは本来キーワードとして定義されるべき構成要素を、互換性維持のためにやむをえず暫定措置としてマクロで定義したものであった[7][8]。C23においてこれらのマクロは廃止となりキーワードとなった。
C++のように、言語自体の機能によって定数やインライン関数およびジェネリックな関数テンプレートを記述可能な言語ではなるべく言語自体の機能を使い、プリプロセッサを排除して記述すべきだという意見が存在するが、互換性や慣習からプリプロセッサを利用した記述が行われる場面は依然多い。Javaではプリプロセッサは採用されなかった。C#では限定されたプリプロセッサが採用された。
また、プリプロセッサを積極的に用いてメタプログラミングを行うといった高度な用法もある。