跳转至

static_assert和assert

  • 功能:
  • static_assert进行编译时断言检查
  • 区别:
  • static_assert是关键字,而assert是宏
  • assert进行运行期检查,而static_assert在编译期检查
  • 示例
#include<assert.h>
int main()
{
    //assert不会在编译期报错,只有运行程序时,执行到这一步采取检查assert中表达式的值
    assert(1 + 2 < 2);
    //static_assert会在编译期检查,如vs会立即报错提示
    static_assert(1 + 2 < 2, "1+2>2");    
}
  • assert源码分析:当在程序中定义NDEBUG宏时,assert宏辉展开成(void)0,这可以使assert不产生任何断言作用。assert展开后先执行!!(expression)表达式,如果真,则得(void)true,否则,执行(_wassert(_CRT_WIDE(#expression), _CRT_WIDE(__FILE__), (unsigned)(__LINE__)), 0),其中_wassert函数作用是将错误信息打印在控制台,并调用std::abort()终止程序。,0的作用是利用逗号表达式的特性使assert宏执行后产生(void)0结果
#ifdef NDEBUG

    #define assert(expression) ((void)0)

#else

    _ACRTIMP void __cdecl _wassert(
        _In_z_ wchar_t const* _Message,
        _In_z_ wchar_t const* _File,
        _In_   unsigned       _Line
        );

    #define assert(expression) (void)(                                                       \
            (!!(expression)) ||                                                              \
            (_wassert(_CRT_WIDE(#expression), _CRT_WIDE(__FILE__), (unsigned)(__LINE__)), 0) \
        )

#endif

注意:(void)0的作用使表达式仅仅可执行,却不能作为左值或右值,如int i=(void)(1+2);将会报错,表达式1+2会执行得到3,但这个值经过void强制转为不完整类型,因此不能给int变量。