1. 程式人生 > >#define assert_param(expr) ((void)0) 這是個巨集定義,(void)0執行的操作

#define assert_param(expr) ((void)0) 這是個巨集定義,(void)0執行的操作

問題:#define assert_param(expr) ((void)0) 這是個巨集定義,但是我真是不知道(void)0能執行什麼操作
具體的定義和用法在下面
void MY_NVIC_SetVectorTable(u32 NVIC_VectTab,u32 Offset)
{
  assert_param(IS_NVIC_VECTTAB(NVIC_VectTab));
  assert_param(IS_NVIC_OFFSET(Offset));
  SCB->VTOR=NVIC_VectTab|(Offset&(u32)0x1FFFFF80);
}
答案:這是斷言機制。意思是在關閉斷言的情況下,
#ifdef  NDEBUG 
#define assert(exp)     ((void)0)
#else
#define assert(exp) (void)( (exp) || (_assert(#exp, __FILE__, __LINE__), 0) )
如果你寫的程式碼中使用了斷言,比如:
assert(i>=0);
那麼這句的在程式中的作用分兩種情況:
1. 若果在assert.h被包含之前NDEBUG這個巨集未定義,assert(exp) 就被定義為(void)( (exp) || (_assert(#exp, __FILE__, __LINE__), 0) )。這樣當i<0時,i>=0這個表示式為假,所以程式就會終止。並通知程式設計師發生錯誤的檔案位置和程式碼行。但是錯誤資訊僅僅對程式設計師有用。對使用者來說,程式異常終止就顯得不是那麼友好了(使用者此時需要的是挽回錯誤)。所以在釋出給使用者的程式中,assert(斷言)要關閉。在VC++6.0下這是通過在包含assert.h標頭檔案之前定義NDEBUG實現的。
2.在定義了NDEBUG的情況下,斷言不應該給程式帶來副作用。這樣斷言就被定義為:
#define assert(exp)     ((void)0)
此時,assert(i>=0);不管括號中表達式為真還是為假,這一行程式碼其實相當於:
NULL;意思是不執行任何操作