在c ++中编译时断言

时间:2013-05-08 09:45:00

标签: c++ generic-programming

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

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将用以上的exssion替换 COMPILE_ASSERT(expr,msg)。但 msg [bool(expr)? 1:-1] CompileAssert&lt;(bool(expr))&gt; 的替代类型。

请有人详细解释一下。我有很多问题。

就像为什么消息(PassRefPtr_should_never_be_assigned_to)在不使用“”for char *

的情况下工作

2 个答案:

答案 0 :(得分:1)

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

我们说bool(expr)true。在这种情况下,typedef等同于

typedef CompileAssert<true> msg[1];

这是CompileAssert<true>结构的1元素数组,名为msg。由于CompileAssert<bool>是一个定义的结构,一切都很好。

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

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

答案 1 :(得分:1)

如果将表达式传递给计算结果为false的宏,则宏将给出如下的typedef:

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

typedef CompileAssert<false> PassRefPtr_should_never_be_assigned_to[-1];

因此,由于不允许使用负数组长度,编译器将为typedef发出错误,包含“msg”作为数组名称。