在常量表达式中可用的断言
Is assert usable in constant expressions?
来自<cassert>
的assert
-宏提供了一种确保满足条件的简明方法。如果参数求值为true
,则不产生任何进一步的影响。但是,在这种情况下,它的调用也可以在常量表达式中使用吗?
这是由LWG 2234处理的,在constexpr
函数的宽松约束引入后又引起了人们的注意。
提出决议:
此措辞与N3936有关。
在17.3中向现有列表引入以下新定义【定义】:
constant subexpression [definitions . consts . subbexpr]
作为条件表达式CE (5.16 [expr.cond])的子表达式的求值不会阻止CE作为核心常量表达式(5.20 [expr.const])。
在19.3[断言]p1后面插入新的段落:
- ?-表达式
assert(
E)
是一个常量子表达式([defns. consts . subbexpr]),如果
NDEBUG
定义在assert(E)出现的地方,或者E上下文转换为
bool
(4 [conv]),是一个常量子表达式,计算结果为true
。
常数表达式
这个解析引入了常量子表达式的概念——本质上,一个表达式本身(不一定)不是常量表达式,但可以在其中使用。例如
constexpr void f() {
int i = 0;
++i;
}
++i
不是一个常量表达式,因为它修改的对象的生存期开始于该表达式之外(§5.20/(2.15))。然而,表达式f()
整体上是一个常量表达式,因为前面的一点不适用——i
的生命周期从f
开始。因此++i
是一个常量子表达式,因为++i
并不阻止f()
成为常量表达式。
和assert
?
解析的第二部分保证assert(
E )
是一个常量子表达式,如果定义了NDEBUG
或者实参本身是一个常量子表达式并且求值为true
。这意味着对assert
的调用也可以是一个标准常量表达式。
以下是格式良好的:
constexpr int check(bool b) {
assert(b);
return 7;
}
constexpr int k = check(true);
b
是一个常量子表达式,在调用check(true)
时求值为true
,因此assert(b)
是一个常量子表达式,因此不妨碍check(true)
成为一个常量子表达式。
当然,与模板中的static_assert
相同的陷阱也是可能的。鉴于NDEBUG
没有定义,这个定义是病态的,不需要§7.1.5/5的诊断:
constexpr void fail() {
assert(false);
}
- #定义c-预处理器常量..我做错了什么
- 用C++中的一个变量定义一个常量
- 什么时候在C++中返回常量引用是个好主意
- 代理对象的常量正确性
- 我想将一个对T类型的非常量左值引用绑定到一个T类型的临时值
- 通过多个头文件使用常量变量
- 在cuda线程之间共享大量常量数据
- 不能在初始值设定项列表中将非常量表达式从类型 'int' 缩小到'unsigned long long'
- 有没有什么方法可以使用一个函数中定义的常量变量,也可以由c++中同一程序中的其他函数使用
- 是默认情况下分配给char数组常量的值
- 私有类型的静态常量成员
- 类似枚举的计算常量
- 递归模板化函数不能分配给具有常量限定类型"const tt &"的变量"state"
- 为什么我可以通过引用修改常量返回
- 如何创建长度由常量参数指定的数组
- 包含 comptime 断言的整数常量表达式宏
- 静态断言用于检查静态常量类数据成员
- 为什么比较 constexpr 函数的两个参数不是静态断言的常量条件
- 初始化一个常量变量,如果失败则断言(c++)
- 在常量表达式中可用的断言