c++中的编译时断言

compile time assertion in c++

本文关键字:断言 编译 c++      更新时间:2023-10-16

我正在阅读一个编译时间断言,在网上搜索后,我得到了一些我不理解的代码。

template <bool> struct CompileAssert {};
#define COMPILE_ASSERT(expr, msg) 
    typedef CompileAssert<(bool(expr))> msg[bool(expr) ? 1 : -1]

如下所示使用COMPILE_ASSERT

COMPILE_ASSERT(!sizeof(T*), PassRefPtr_should_never_be_assigned_to)

但我不明白。有人能帮助我理解上面的代码吗?第二,我对这段代码感到困惑

typedef CompileAssert<(bool(expr))> msg[bool(expr) ? 1 : -1]

#define将用上述表达式替换COMPILE_ASSERT(expr, msg)。但是如何msg[bool(expr) ?[1: -1]的另一种类型CompileAssert<(bool(expr))>

请有人详细而简单地解释一下。我有很多很多问题。

喜欢为什么消息(PassRefPtr_should_never_be_assigned_to)不使用char *

如果将表达式传递给计算结果为false的宏,宏将给出如下类型定义:

typedef CompileAssert<false> PassRefPtr_should_never_be_assigned_to[false ? 1 : -1];

typedef CompileAssert<false> PassRefPtr_should_never_be_assigned_to[-1];

因此,由于不允许负数组长度,编译器将为typedef发出错误,其中包含"msg"作为数组名。

typedef将根据expr的值命名合法或非法的代码段。

假设bool(expr)true。在这种情况下,类型定义等价于

typedef CompileAssert<true> msg[1];

这是一个包含CompileAssert<true>结构体的1元素数组,命名为msg。由于CompileAssert<bool>是一个已定义的结构,所以一切正常。

但是,如果bool(expr)false,则类型定义将等同于以下内容:

typedef CompileAssert<false> msg[-1];

这当然是非法的(您不能创建大小为-1的数组),因此编译器将报告msg格式错误的错误。由于msg是宏参数,它实际上是COMPILE_ASSERT中提供的文本,因此您的示例的错误消息可能看起来像这样:

Cannot create array PassRefPtr_should_never_be_assigned_to of size -1.

还要注意c++ 11有一个内置的static_assert