無法訪問程式碼的斷言

在開發過程中,當必須阻止某些程式碼路徑到達控制流時,你可以使用 assert(0) 來指示這樣的條件是錯誤的:

switch (color) {
    case COLOR_RED:
    case COLOR_GREEN:
    case COLOR_BLUE:
        break;

    default:
        assert(0);
}

只要 assert() 巨集的引數計算為 false,巨集就會將診斷資訊寫入標準錯誤流,然後中止程式。此資訊包括 assert() 語句的檔案和行號,在除錯時非常有用。可以通過定義巨集 NDEBUG 來禁用斷言。

發生錯誤時終止程式的另一種方法是使用標準庫函式 exitquick_exitabortexitquick_exit 採用可以傳遞迴你環境的引數。abort()(以及 assert)可能是一個非常嚴重的程式終止,並且可能無法執行在執行結束時執行的某些清理。

assert() 的主要優點是它可以自動列印除錯資訊。呼叫 abort() 的優點是不能像斷言一樣禁用它,但它可能不會導致顯示任何除錯資訊。在某些情況下,同時使用這兩種結構可能是有益的:

if (color == COLOR_RED || color == COLOR_GREEN) {
   ...
} else if (color == COLOR_BLUE) {
   ...
} else {
   assert(0), abort();
}

啟用斷言後,assert() 呼叫將列印除錯資訊並終止程式。執行永遠不會到達 abort() 呼叫。當斷言被禁用時assert() 呼叫什麼都不做,並且呼叫 abort()。這可確保程式始終終止此錯誤條件; 啟用和禁用斷言僅影響是否列印除錯輸出。

你永遠不應該在生產程式碼中留下這樣的資訊,因為除錯資訊對終端使用者沒有幫助,因為 abort 通常是一個非常嚴格的終止,它會禁止為 exitquick_exit 執行安裝的清理處理程式。