プリプロセッサ

出典: フリー百科事典『ウィキペディア(Wikipedia)』
ナビゲーションに移動 検索に移動

プリプロセッサ (: preprocessor) とは、一般にある処理を行うソフトウェアに対して、データ入力やデータ整形などの準備的な処理を行うソフトウェアのことである。

他の分野の例としては、CADCAEのデータ処理がある。またワープロソフトウェアにおける漢字変換ソフトウェアもプリプロセッサの一例である。

プログラミング言語のプリプロセッサ[編集]

プログラミング言語処理系においては、ソースコードに対して、それらがインタプリタコンパイラなどの本体に渡される前に、前処理を施すプログラムがプリプロセッサと呼ばれている。

そういったソースコード中には、プリプロセッサに対する指令などが含まれており、それらは「プリプロセッサ指令」(プリプロセッサディレクティブ)などと呼ばれている。処理自体は「プリプロセス」(preprocess) と呼ばれる。

処理内容[編集]

以下のようなものがある(実際には、各言語あるいはプリプロセッサ次第であって、以下に挙げられているものは全て任意の例である)。

  • ファイルの読み込み (including)
  • マクロの展開(シンボルを、あらかじめ定義された規則に従って置換する)
  • コンパイル条件によるソースコードの部分的選択
  • コメントの削除

環境[編集]

プリプロセッサを用いる言語の一例としてC言語がある。GNUプロジェクトのcppコマンド (C preprocessor) はよく使われているプリプロセッサである。cppコマンドを明に実行しなくても、C言語コンパイラのccコマンドやgccコマンドはその内部でプリプロセッサを先に実行させることができる。

また、言語仕様の貧弱な言語を構造化プログラミングができるようにしたものもある。ratforFORTRANのプリプロセッサ)が有名である。

そのほかにも、FORTRANやCOBOLのプリプロセッサが商用のツールとして、メインフレーム向けに販売されている。

注意点[編集]

プリプロセッサを通すことを前提に記述されたプログラムは、コンパイラのあずかりしらない内容を含んでいることになる。このことは、たとえばマクロの定義と同じ文字列が(意図せず)全て変換されてしまったり、定数の型をチェックできなかったりと、問題の火種をはらんでいる。そのため、プリプロセッサを用いる場合には注意が必要である。

このような名前衝突の問題をさけるための対策として、少なくともユーザー定義のマクロの識別子は大文字だけで記述し、それ以外の識別子は小文字をまぜるという慣習がある[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にて例示されたマクロには、すべて大文字のものもあれば、すべて小文字のものもある。標準Cライブラリも同様であり、例えばassert()は規格でマクロであることが規定されているにもかかわらずすべて小文字である。getc()関数やputc()関数、errnoなどはマクロによる実装を規格で許可している。また、FILE型はマクロであることが規定されていない(規格では「オブジェクト型」としか規定されていないが、通例は構造体で実装される[4])にもかかわらずすべて大文字である[5]。なお、後発のC99規格やC11規格でもbool, true, false, offsetof(), noreturnなど[6][7][8]、依然として小文字のマクロが標準仕様として追加導入されている。ただし、これらは本来キーワードとして定義されるべき構成要素を、互換性維持のためにやむをえずマクロとして定義したものである[9][10]。なお、C99やC11で新しく追加されたこれらの小文字のマクロは、C言語の次期規格であるC2xにおいて廃止しキーワードとすることが検討されている[10]

C++のように、言語自体の機能によって定数やインライン関数およびジェネリックな関数テンプレートを記述可能な言語ではなるべく言語自体の機能を使い、プリプロセッサを排除して記述すべきだという意見が存在するが、互換性や慣習からプリプロセッサを利用した記述が行われる場面は依然多い。Javaではプリプロセッサは採用されなかった。C#では限定されたプリプロセッサが採用された。

また、プリプロセッサを積極的に用いてメタプログラミングを行うといった高度な用法もある。

脚注[編集]

  1. ^ "C++の設計者Bjarne Stroustrupによる注意:「すべての文字を大文字にした名前は慣例的にマクロでの使用に予約されているので、絶対に使用しないでください」"
  2. ^ ISBN 978-4839921941 "Code Craft ~エクセレントなコードを書くための実践的技法~" p.570
  3. ^ 標準Cライブラリにも小文字のマクロassert()や大文字のFILE型が存在するが、これらは脚注の「Code Craft エクセレントなコードを書くための実践的技法」にあるように危険性が認知される以前の名残である。
  4. ^ [迷信] FILE 型は構造体 | 株式会社きじねこ
  5. ^ 初期の実装において、FILEの定義にマクロが使われていたことに由来する。Version 7 Unixの例:V7/usr/include/stdio.h
  6. ^ ブーリアン型サポートライブラリ - cppreference.com
  7. ^ C99規格では、booltypedefではなくマクロで実装することを規定している。
  8. ^ Type support - cppreference.com
  9. ^ ISO/IEC JTC1/SC22/WG14 N609
  10. ^ a b Revise spelling of keywords and make them feature tests; proposal for C2x

関連項目[編集]

外部リンク[編集]