2011-11-16 65 views
6

看看這個代碼:空「釋放」ASSERT宏崩潰程序?

#include <cassert> 

#ifdef DEBUG 
#define ASSERT(expr) assert(expr) 
#else 
#define ASSERT(expr) 
#endif /* DEBUG */ 

程序將只運行,如果我有定義DEBUG,否則會掛起,並且沒有結果終止。我在Eclipse Indigo CDT中使用MinGW。建議表示讚賞!

回答

7

您幾乎肯定是濫用斷言。斷言表達絕不能有副作用

當你說,assert(initialize_critical_space_technology());,然後你在發佈版本中省略這整行,你可以想象自己會發生什麼。

使用斷言的唯一安全和明智的方式是關於價值觀:

const bool space_init = initialize_critical_space_technology(); 
assert(space_init); 

有人介紹VERIFY宏觀的東西,總是執行代碼:

#define VERIFY(x) (x)   // release 
#define VERIFY(x) (assert(x)) // debug 
8

如果不查看造成問題的實際代碼,很難說清楚。我的猜測是:你在ASSERT()內評估一個帶有副作用的表情。例如,ASSERT(++i < someotherthing)在一個循環中。您可以通過臨時修改宏定義exprNDEBUG構建來確認。確認這是原因之後,請轉到您發出的每個呼叫以確保表達式是免費的副作用。

+0

這可能是第二個最調試和發佈版本之間差異的常見原因(優化之後)。 –

+0

感謝您的回答,只有一個問題。對於非調試,「#define ASSERT(expr)(expr)'(就像Kerrek SB提到的那樣)是否是好的做法,並且不必擔心那裏的副作用?我有一種感覺,這會讓我的代碼更具可讀性。 – AutoBotAM

+0

@AutoBotAM:如果你改用'ASSERT'' VERIFY',那麼確定,繼續。但不要重新定義'ASSERT',人們知道並期望它不會評估'NDEBUG'構建中的表達式。 –