看看這個代碼:空「釋放」ASSERT宏崩潰程序?
#include <cassert>
#ifdef DEBUG
#define ASSERT(expr) assert(expr)
#else
#define ASSERT(expr)
#endif /* DEBUG */
程序將只運行,如果我有定義DEBUG
,否則會掛起,並且沒有結果終止。我在Eclipse Indigo CDT中使用MinGW。建議表示讚賞!
看看這個代碼:空「釋放」ASSERT宏崩潰程序?
#include <cassert>
#ifdef DEBUG
#define ASSERT(expr) assert(expr)
#else
#define ASSERT(expr)
#endif /* DEBUG */
程序將只運行,如果我有定義DEBUG
,否則會掛起,並且沒有結果終止。我在Eclipse Indigo CDT中使用MinGW。建議表示讚賞!
您幾乎肯定是濫用斷言。斷言表達絕不能有副作用。
當你說,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
如果不查看造成問題的實際代碼,很難說清楚。我的猜測是:你在ASSERT()
內評估一個帶有副作用的表情。例如,ASSERT(++i < someotherthing)
在一個循環中。您可以通過臨時修改宏定義expr
NDEBUG
構建來確認。確認這是原因之後,請轉到您發出的每個呼叫以確保表達式是免費的副作用。
這可能是第二個最調試和發佈版本之間差異的常見原因(優化之後)。 –
感謝您的回答,只有一個問題。對於非調試,「#define ASSERT(expr)(expr)'(就像Kerrek SB提到的那樣)是否是好的做法,並且不必擔心那裏的副作用?我有一種感覺,這會讓我的代碼更具可讀性。 – AutoBotAM
@AutoBotAM:如果你改用'ASSERT'' VERIFY',那麼確定,繼續。但不要重新定義'ASSERT',人們知道並期望它不會評估'NDEBUG'構建中的表達式。 –