assert 實現分析

一直以來,對於assert的實現老是不太理解,如今深刻assert背後的代碼,總算對assert的實現有了一個清醒的認識。函數

assert基於宏定義與宏展開實現。首先介紹一下assert的功能:它可以斷言給定表達式是否爲true。若是爲true,則對應assert的代碼會轉換爲static_cast<void>(0),即一條空語句,assert不執行任何操做,不然assert對應的代碼會展開爲__assert_fail (__STRING(expr), __FILE__, __LINE__, __func__)),使用expr參數,源代碼名,assert所在的行數以及函數名調用__assert_fail函數,輸出錯誤信息,而且由於斷言出錯而終止程序。請注意,在調用函數__assert_fail時,assert將傳入的參數轉換爲字符串輸入,這一點只需查看__STRING(x)的定義:#define __STRING(x) #x便可明白。code

咱們知道,在編譯源代碼的時候,若是咱們定義了NDEBUG,那麼assert不會起任何做用,哪怕傳入的參數爲false,這是爲何呢?由於在assert外層還有一個宏判斷語句,若是定義了NDEBG,那麼assert語句統一轉換成static_void<void>(0)進行處理,因此不會對傳入的參數進行任何判斷。字符串

下面附上相關代碼,相信你如今會對assert有更加清晰的認識!編譯

// (爲了便於閱讀,代碼進行了部分修改)
#define __STRING(x) #x

#ifdef NDEBUG
# define assert(expr)       (static_cast<void>(0))
#else
# define assert(expr)                           \
  ((expr)                               \
    ?static_cast<void>(0)                       \
   : __assert_fail (__STRING(expr), __FILE__, __LINE__, __func__))
#endif
相關文章
相關標籤/搜索