Lemon Parser Generatorで生成されるコードには(というよりも、lempar.cによれば)、staticな関数とstaticでない関数がある。ヘッダオンリーで扱いたいのでstaticでない関数にはinlineを付けておきたい。%nameが指定されていない場合のstaticでない関数は下記になる。これらをエクスポートされる関数と呼ぼう。

void ParseTrace;
void *ParseAlloc;
void ParseFree;
int ParseStackPeak;
void ParseFree;

普通に考えると、lempar.cを変更するのが一番楽だ。あるいは、後処理でinlineを付けてもよい。awkで書くとこんな感じ。

awk '/^(void|int)/ { print "inline", $0 }; { print }'

しかしだ。既にマクロが使用されている以上、毒をくらわば皿までである。ちなみに、エクスポートされる関数は、生成されたコードのなかで参照されていないので、こういうことができる。

#define ParseTrace     inline ParseTrace
#define ParseAlloc     inline ParseAlloc
#define ParseFree      inline ParseFree
#define ParseStackPeak inline ParseStackPeak
#define ParseFree      inline ParseFree

邪悪すぎる。

そもそものところに立ち返ると、inlineを付けるという発想がよろしくない。それぞれの翻訳単位に、同じ名前の関数の定義がばらまかれてしまうのが問題だった。Cならばともかく、C++には無名名前空間がある。これによって、関数の定義はばらまかれるが、それぞれはお互いに異なる名前を持つことになる。いや、ばらまかれるのは変わらないんだけれども。

コメントをかく


「http://」を含む投稿は禁止されています。

利用規約をご確認のうえご記入下さい

メンバーのみ編集できます