2010-06-21

BOOST_PREVENT_MACRO_SUBSTITUTIONについて

Appleマクロの恐怖 - Faith and Brave - C++で遊ぼう

Appleのクソヘッダーがcheckとかrequireとかverifyなどといった、あまりにも一般的すぎる単語をプリプロセッサーマクロで定義している問題。MSも、あの悪名高いminやmaxマクロを定義している。

最良の解決策は、そんなクソマクロを定義したヘッダーを使わないこと。

ところで、#2115 (Avoid bad Apple macros) – Boost C++ Librariesをみると、BOOST_PREVENT_MACRO_SUBSTITUTIONというものがあり、これを使えば、この問題を解決できるらしい。何と、そんな便利なものがあるのか。早く言ってよね。しかし、なぜか、"Perhaps sadly, I have to agree."と言われている。何故そんなに落ち込んでいるのだろうか。気になる。さっそく、実装を見てみた。

// boost\config\suffix.hpp
// 実装
#define BOOST_PREVENT_MACRO_SUBSTITUTION

なんじゃこりゃ。ドキュメントが見つからないが、とりあえず、使い方は分かった。そして、絶望した。以下のようなコードがあったとする。

// クソなマクロ
#define check(x) (x)

int check(int x ) { return x ; }

int main()
{
    check(0) ;
}

このままでは、checkというクソなマクロのせいで、コンパイルエラーになってしまう。そこで、BOOST_PREVENT_MACRO_SUBSTITUTIONの登場だ。

// 以下のマクロの為、#include
// #define BOOST_PREVENT_MACRO_SUBSTITUTION
#include <boost/config.hpp>

// クソなマクロ
#define check(x) (x)

int check BOOST_PREVENT_MACRO_SUBSTITUTION (int x ) { return x ; }

int main()
{
    check BOOST_PREVENT_MACRO_SUBSTITUTION (0) ;
}

ようは、function-like macroというのは、名前(引数)の形で使うのだから、名前と左括弧の間に、なにか別のobject-like macroをいれてやれば、マクロの適用を阻害できるのだ。

なるほど、それで、"Perhaps sadly, I have to agree."なわけか。

No comments: