現在開発中のプリプロセッサについて
(0) 大前提として
- 私は同じものを作るときは同じようには作りません。
- いきなりわかりにくい表現になってしまいましたが、つまり私がプリプロセッサを作る場合、既存の完全な互換品を目指すことはなく、何らかの拡張機能を必ず入れるということです。
(1) 多重define
- 普通のプリプロセッサでは、マクロ Abc が定義済みの時に、さらに Abc を定義しようとすればすぐにエラーになります。
- でも私のプリプロセッサではエラーにはならず、新しい定義が有効になります。
- そして Abc を undef すると、定義は前の定義内容に戻ります。
- これの何がうれしいのか?
- 何らかのコード片があったとします。・・・C言語ではコード片を持ってきたときに、全体を { } でくくってしまえば、変数名の衝突を気にすることなく正しく動きます。
- でも #define があるとこの限りではないのです。他とぶつかっていたら、ぶつからない名前にその都度調整しなければいけません。
- しかし私の仕様になっていれば、ぶつかっていても気にすることはなく、最後に undef しておけば、プログラムのほかの場所に迷惑をかけることもないのです。
- この機能は、 #define / #undef ではなく、 #.def / #.undef として実装しています。
- #define / #undef には従来通り多重定義を認めず、また復元などの機能は持たせていません。従来のプログラムが、予期せぬ挙動のせいでバグになったら困るからです。
(2) マクロのオーバーロード
- C → C++ での進歩点として、「同じ関数名であっても、引数の個数や型が違えば、それらは正しく区別される」という機能が追加されています。関数のオーバーロードと言われているものです。
- それならば、プリプロセッサマクロもオーバーロード可能にしてやろうと思いました。
- ただしプリプロセッサの引数に型はないので、マクロの識別は引数の数だけです。
- つまり、 Abc(1,2) と Abc(1,2,3) は別のマクロです。
(3) 複数行マクロ
- 普通のプリプロセッサでは、マクロは1行で書かなければいけません。
- この制約から逃れるために、行末にバックスラッシュを書いて、行をつないでいました。
- しかしこれがみっともないのです。
- 私のプリプロセッサでは、[^ ... ^] でくくって定義することで、複数行での定義が可能になっています。また [^ ... ^] の中に、 #if や #.def などを書くことも可能です。
- この機能によって、 C++ のテンプレートに近いこともできます。・・・つまり構造体や関数を定義するためのマクロを書いて、引数に応じて関数定義などが変わるようにすればいいのです。
(4) 追加型マクロ
こめんと欄
|