編譯斷言技術現在被越來越多的使用。其目的在於讓更多的錯誤在編譯階段被暴露,以便於更早的發現隱藏的bug。C++11中,提供了static_assert來用作編譯斷言,而對於還不支持C++11的地方,需要自己實現Compile-time-assertion。Compile-time-assertion的實現其實並不難,無非是定義一些非法的語句,讓編譯器報錯即可。
WebKit中,被廣泛使用的Compile-time-assertion是COMPILE_ASSERT,其實現如下:
/* COMPILE_ASSERT */
#ifndef COMPILE_ASSERT
#if COMPILER_SUPPORTS(C_STATIC_ASSERT)
/* Unlike static_assert below, this also works in plain C code. */
#define COMPILE_ASSERT(exp, name) _Static_assert((exp), #name)
#elif COMPILER_SUPPORTS(CXX_STATIC_ASSERT)
#define COMPILE_ASSERT(exp, name) static_assert((exp), #name)
#else
#define COMPILE_ASSERT(exp, name) typedef int dummy##name [(exp) ? 1 : -1]
#endif
#endif
其中,#define COMPILE_ASSERT(exp, name) typedef int dummy##name [(exp) ? 1 : -1],當exp是false的時候,dummy#name定義的數組長度為-1,從而編譯器報錯。
對於Compile-time-assertion的實現並不難,只需要構造一個編譯錯誤即可。真正比較困難的是如何定義Compile-time-assertion條件, 該條件的值必須在編譯階段就已經知道。WebKit中,絕大多數COMPILE_ASSERT都用在使用sizeof比較大小,因為sizeof的值是在編譯階段即可確定的,另外就是用在靜態常量值得比較,靜態常量也是在編譯階段值必須確定。