提问者:小点点

glvalue积分常量表达式是常量表达式吗?


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冲突?


共1个答案

匿名用户

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。