3

N4527 5.20 [expr.const]p3

整型常量表达式是整型或无范围枚举类型的表达式,隐式转换为纯右值,其中转换后的表达式是核心常量表达式。

5.20 [expr.const]p5

一个常量表达式要么是一个左值核心常量表达式,其值是指一个实体,该实体是一个常量表达式(如下定义)的允许结果,要么是一个纯右值核心常量表达式,其值是一个对象,对于该对象及其子对象:

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

4

1 回答 1

0

a整数常量表达式吗?

在以下情况下:

int b[a]{};
static_assert(a,"");
switch(1){
  case a:
    ;
}

是的,a是一个整数常量表达式。从您的第一个报价开始:

整型常量表达式是整型或无范围枚举类型的表达式,隐式转换为纯右值,其中转换后的表达式是核心常量表达式。

'a' 是一个整数类型,在您的情况下它将被隐式转换为纯右值,所以现在是a核心常量表达式吗?是的,如果我们回到定义什么不是核心常量表达式的第 2 段:

条件表达式 e 是核心常量表达式,除非按照抽象机 (1.9) 的规则对 e 的求值将求值以下表达式之一

它有以下条款:

左值到右值的转换(4.1),除非它应用于

除了以下例外:

一个整数或枚举类型的非易失性左值,它引用一个完整的非易失性 const 对象,该对象具有前面的初始化,用常量表达式初始化,或

这适用于,a因为它是非易失性的, const 并用常量表达式初始化。


a常量表达式吗?

在与上述相同的上下文中,是的,因为我们可以从上面的引用中看到它是一个核心常量表达式。


泛左值整数常量表达式是常量表达式吗?

不,为了使其成为一个整数常量表达式,它必须转换为纯右值,并且因此不能是泛左值。

于 2015-07-21T02:43:43.070 回答