2013-03-16 97 views
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 

爲什麼這是一個很好的規則,什麼特別之處MIN和MAX函數需要此規則?

回答

8

意外宏替換是無意使用其名稱與功能矛盾的宏。

情況維拉++的檢查被設計爲防止行爲不端系統頭時發生 - 最著名<windows.h> - 定義minmax宏具有相同名稱的或甚至與標準庫函數如std::min<T>std::max<T>應用程序定義的功能干擾,和std::numeric_limits<T>::min()。 (其他名字已經知道導致衝突也是如此。)

由於宏不是名稱空間感知,調用功能std::min(...)沒有幫助,因爲min仍然由預處理擴大。要解決這個問題,這樣的功能,必須調用爲(function)(args...),這將阻止,只要它被定義爲#define function(arg1, arg2) ...,因爲通常是與minmax的情況下宏擴展。另一個可用的選項是#undef它們在使用之前,但包括錯誤標題之後。 Boost提供了自己的替代預防標記,儘管它的自描述被它引入的混亂所抵消。

如果你控制納入<windows.h>,你也可以#define NOMINMAX其列入,這將指導windows.h沒有定義minmax宏之前。

+0

+1。完全與我原先認爲的問題無關。我記得除了最小和最大值之外,還有一些其他的。 – WhozCraig 2013-03-16 16:07:06

+0

BOOST_PREVENT_MACRO_SUBSTITUTION僅僅是「#定義BOOST_PREVENT_MACRO_SUBSTITUTION」(它沒有定義的任何值)。僅僅因爲他們爲宏選擇了一個描述性的名字,這是不可讀的。 – 2013-03-16 16:20:11

+0

'#定義NOMINMAX'也有幫助。 – chris 2013-03-16 16:30:23

0

的問題是,討厭的圖書館(或愚蠢的程序員)通常會定義最大和最小的宏,你可能沒有想到。如果你的代碼假設評估將由一個很好的函數完成,你會得到不正確的結果(甚至是未定義的行爲)。 Linter在指出這一點時很有幫助,除非您確定知道所有包含的宏所定義的宏,否則不會冒這種常見宏名稱衝突的風險。