Cプリプロセッサ(CPP)は、単なるテキストからテキストへの変換ツールとして誤解されることがよくあります。実際には、C標準では、ソースコードをCトークンのストリームへと変換する一連のフェーズとして定義されています。多くの実装では可視性のためにテキスト出力を提供していますが、その根本的なメカニズムは、Cパーサーのために翻訳ユニットを準備するように設計されています。David Priver氏は、独自のC2Yコンパイラとインタプリタを開発する過程で、カスタムCPPを実装し、プリプロセッサをより表現力豊かにし、デバッグを容易にするためのいくつかの拡張機能を導入しました。

これらの拡張機能の主な目的の一つは、「プリプロセッサの乱用」の必要性を減らすことです。これは、標準のCPPに欠けている機能をシミュレートするために使用される、複雑で入れ子になったマクロ定義を指します。例えば、Priver氏は`__print(...)`と`__where()`を組み込みのデバッグマクロとして導入しました。`__print()`は引数を展開し、それらを直接stderrに書き込むため、開発者は翻訳ユニット全体をダンプすることなく、マクロが正確に何に展開されるかを確認できます。`__where()`はマクロが定義された特定のファイルと行を特定し、大規模なコードベースにおいて不明瞭な展開を追跡するという一般的な問題を解決します。

リストの変換を処理するために、Priver氏は`__map(macro, ...)`という組み込み関数を追加しました。標準的なCにおいて、シーケンス内のすべての引数に変換を適用するには、通常、再帰的な関数のようなマクロが必要ですが、C標準は展開を抑制することでこれを制限しています。開発者は手動で反復を回すことで再帰を「偽装」することもできますが、それは多くの場合低速で視覚的にも煩雑です。`__map()`組み込み関数は、線形スキャンを実行して提供されたマクロを各引数に一度適用することで、これを簡素化します。さらに、彼は可変引数マクロの処理を簡素化するために`__VA_COUNT__`組み込み関数を含め、開発者が複雑な手動カウント技術に頼ることなく、直接引数の数を取得できるようにしました。これらの追加は、一般的なメタプログラミングパターンに対するネイティブなサポートを提供することで、プリプロセッサをより強力で読みやすいツールにすることを目指しています。