斷言
assert
和 static_assert
都是 assert.h
中定義的巨集。
assert
的定義取決於標準庫未定義的巨集 NDEBUG
。如果定義了 NDEBUG
,assert
是一個 no-op:
#ifdef NDEBUG
# define assert(condition) ((void) 0)
#else
# define assert(condition) /* implementation defined */
#endif
關於 NDEBUG
是否應該總是用於生產編輯的意見不一。
- 親陣營認為
assert
呼叫abort
並且斷言訊息對終端使用者沒有幫助,因此結果對使用者沒有幫助。如果你有檢查生產程式碼的致命條件,你應該使用普通的if/else
條件和exit
或quick_exit
來結束程式。與abort
相比,這些允許程式進行一些清理(通過atexit
或at_quick_exit
註冊的功能)。 - 該陣營認為,
assert
呼叫永遠不應該在生產程式碼中啟用,但如果他們這樣做,則檢查的條件意味著存在嚴重錯誤,如果執行繼續,程式將會出錯。因此,最好讓斷言在生產程式碼中處於活動狀態,因為如果它們觸發,那麼地獄已經鬆動了。 - 另一個選擇是使用一個自制的斷言系統,它總是執行檢查,但在開發(適當的時候)和生產(“意外的內部錯誤 - 請聯絡技術支援”可能更合適)之間處理錯誤的方式不同。
static_assert
擴充套件為 _Static_assert
這是一個關鍵字。在編譯時檢查條件,因此 condition
必須是常量表示式。在開發和生產之間不需要對此進行不同的處理。