プリプロセッサに関する既知の問題

プリプロセッサによるメタプログラミングは忌避される話題である。 これは例えば、インライン関数をマクロで定義するなどの、 危険な技を伴う良くない経験が一因である。 もしプリプロセッサを使わずにすむ良い方法があるのであれば、そのようにするべきだ。
ではプリプロセッサのよく知られた問題のいくつかを、問題/解決法形式で見てみよう。

問題 #1

プリプロセッサはスコープが無い。したがってマクロは予期しないコードの置換をおこしてしまうことがある。
解決法 A
全て大文字からなる識別子をマクロに使い、それらをマクロ以外では使わない。 実際この方法は予期せずコードが置換されてしまう可能性を除去する。
解決法 B
ローカルマクロ慣用法を使う:
#define MACRO ...
// use MACRO
#undef MACRO
これは特定の部分以外のコードをそのマクロによって予期せず置換されてしまうことを防ぐ。
この解決法の欠点は、#undefは自動的に付けられるわけではないため、忘れることがある、というものだ。 経験を積んだプログラマは、そのマクロを定義した(時間的に)直前または直後に#undefを書く。
解決法 C
特定の接頭語をマクロに付ける。
#define UMP_MACRO
// use UMP_MACRO
これは予期せぬ置換と衝突をめったに起こらなくする。 この解決法の欠点は次のようなものである:
全ての解決法を可能な限り組み合わせて、スコープの問題は大抵は除去できる。

問題 #2

プリプロセッサコードは読みにくい。 プリプロセッサがどのようにして再帰的にマクロを展開するかを理解する必要があるし、マクロの定義を見つけたり、マクロのパラメータを頭の中で置換する必要もある。
解決法
いかなる種類のプログラミングもそのコードがどのように実行されるか理解しなければならない。 関数やテンプレートを含むいかなるパラメータ化の技術においても、定義を見つけ、頭の中でパラメータを置換する必要がある。
しかしながら、いくつかの技を知っておくことは有益である:
特に覚えておくべき重要なことは、プリプロセッサの使用を、構造化され、理解しやすく、安全な手段に制限することである。 構造化は複雑なシステムを理解しやすくする[McConnell]

問題 #3

「私はcppを廃止してしまいたい。」 - Bjarne Stroustrup in [Stroustrup]
解決法
C/C++ プリプロセッサは末永く存続する。
実際問題としては、プリプロセッサによるメタプログラミングは決してテンプレートメタプログラミングほど単純でもポータブルでも無い [Czarnecki]

© Copyright Housemarque Oy 2002
Permission to copy, use, modify, sell and distribute this document is granted provided this copyright notice appears in all copies.  This document is provided "as is" without express or implied warranty and with no claim as to its suitability for any purpose.