N4527 5.20[expr. const]p3
整型常量表达式是整型或无作用域枚举类型的表达式,隐式转换为正则表达式,其中转换后的表达式是核心常量表达式。
5.20[expr. const]p5
常量表达式要么是glvalue core常量表达式,其值引用一个实体,该实体是常量表达式(定义如下)的允许结果,要么是prvalue core常量表达式,其值是一个对象,其中对于该对象及其子对象:
(5.1)-引用类型的每个非静态数据成员都引用一个实体,该实体是常量表达式的允许结果,并且
(5.2)-如果对象或子对象是指针类型,则它包含具有静态存储持续时间的对象的地址、此类对象(5.7)末尾之后的地址、函数的地址或空指针值。
如果实体是具有静态存储持续时间的对象,并且不是临时对象或其值满足上述约束的临时对象,或者它是一个函数,则实体是常量表达式的允许结果。
void foo(){
const int a = 1;//a has automatic storage duration
// all ok in gcc 5.1.0 and clang 3.8.0
int b[a]{};
static_assert(a,"");
switch(1){
case a:
;
}
}
问题1:a
是整数常量表达式吗?
问题2:a
是常量表达式吗?
问题3:glvalue积分常量表达式是常量表达式吗?
问题4:
如果问题3的答案是肯定的,如果对象有自动存储时长,这是否与5.20 p3冲突?
a
是整数常量表达式吗?
在以下情况下:
int b[a]{};
static_assert(a,"");
switch(1){
case a:
;
}
是的,a
是一个整数常量表达式。从您的第一个引号开始:
整型常量表达式是整型或无作用域枚举类型的表达式,隐式转换为正则表达式,其中转换后的表达式是核心常量表达式。
'a'是一个整数类型,在您的情况下,它将被隐式转换为prvalue,那么现在a
是一个核心常量表达式吗?是的,如果我们回到第2段,它定义了什么不是核心常量表达式:
条件表达式e是核心常量表达式,除非e的求值遵循抽象机器(1.9)的规则,将求值以下表达式之一
它有以下条款:
左值-右值转换(4.1),除非它应用于
但以下情况除外:
整数或枚举类型的非易失性glvalue,它引用具有前面初始化的完整非易失性const对象,使用常量表达式初始化,或
这适用于a
,因为它是非易失性的、const并且使用常量表达式初始化。
a
是常量表达式吗?
在与上述相同的上下文中,是的,因为我们可以从上面的引号中看到它是一个核心常量表达式。
glvalue积分常量表达式是常量表达式吗?
不,为了使它成为一个整数常数表达式,它必须转换为一个纯值,因此不能是一个glvalue。