7

偶発的なマクロ置換とは

Vera++ C++ リンターでは、ルール T016 は次のように述べています。

min 関数と max 関数の呼び出しは、偶発的なマクロ置換から保護する必要があります。

x = max(y, z); // wrong, vulnerable to accidental macro substitution

x = (max)(y, z); // OK

x = max BOOST_PREVENT_MACRO_SUBSTITUTION (y, z); // OK

なぜこれが良いルールなのですか? また、このルールを必要とする最小関数と最大関数の何が特別なのですか?

4

2 に答える 2

8

偶発的なマクロ置換は、名前が関数と競合するマクロを意図せずに使用することです。

Vera++ のチェックが防止するように設計されている状況は、システム ヘッダーの誤動作 (最も有名な例) が、同じ名前のアプリケーション定義関数や、 、、などの標準ライブラリ関数にさえ干渉するマクロを<windows.h>定義minしている場合に発生します。(他の名前も衝突を引き起こすことが知られています。)maxstd::min<T>std::max<T>std::numeric_limits<T>::min()

マクロは名前空間を認識しないため、関数を as として呼び出しても、 はプリプロセッサによって展開されたままになるため、役に立ちません。この問題を回避するには、そのような関数を として呼び出す必要があります。これにより、 と で通常行われるように、 として定義されている場合、マクロ展開が防止されます。別の利用可能なオプションは、使用する前ですが、不正なヘッダーを含めた後です。Boost は独自の置換防止マーカーを提供しますが、その自己記述性は、Boost が導入する煩雑さによって相殺されます。std::min(...)min(function)(args...)#define function(arg1, arg2) ...minmax#undef

の組み込みを制御する場合は、その組み込みの前に<windows.h>行うこともできます。これにより、およびマクロを定義しないように指示されます。#define NOMINMAXwindows.hminmax

于 2013-03-16T16:05:32.713 に答える
0

問題は、意地悪なライブラリ (または愚かなプログラマー) が一般的に、予期しない max および min マクロを定義することです。あなたのコードが評価がナイス関数によって行われると想定している場合、間違った結果 (または未定義の動作) が得られます。リンターは、使用しているすべてのインクルードによって定義されたすべてのマクロを本当に知っていると確信していない限り、そのような一般的なマクロ名と衝突するリスクを冒さない方が安全であることを指摘することで役に立ちます.

于 2013-03-16T16:07:29.803 に答える