一个glvalue整数常量表达式是一个常量表达式吗?

3

N4527 5.20 [expr.const]p3

整数常量表达式是指具有整数或无作用域枚举类型的表达式,隐式转换为prvalue,并且转换后的表达式是核心常量表达式。

5.20 [expr.const]p5

常量表达式指的是以下定义的常量表达式的值引用一个被允许的常量表达式实体的glvalue(其中该实体可以是一个非静态数据成员)或者一个其值为对象的prvalue 的核心常量表达式,对于该对象及其子对象:

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


2
请按照一个问题一个问题的方式提问。只能一个问题,不能五个问题。 - Lightness Races in Orbit
@Lightness Races in Orbit 主要问题是4,但如果3不成立,则没有必要问4,以此类推。1、2和3是4的一部分。 - stackcpp
仅当应用lvalue-to-rvalue转换时。 - aschepler
@KerrekSB a是一个核心常量表达式,因为它满足[expr.const]/(2.7.1)。 - stackcpp
然后将其改写为一个问题。 - Lightness Races in Orbit
显示剩余11条评论
1个回答

0
在编程中,以下情况中的 a 是否为整数常量表达式?
int b[a]{};
static_assert(a,"");
switch(1){
  case a:
    ;
}

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

整数常量表达式是指整数或未作用域枚举类型的表达式,隐式转换为 prvalue,其中转换后的表达式是核心常量表达式。

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

条件表达式 e 是核心常量表达式,除非按照抽象机器(1.9)的规则评估 e 会评估以下表达式之一

它有以下条款:

lvalue-to-rvalue 转换(4.1),除非应用于

有以下例外:

非易失性 glvalue,其引用完整的非易失性 const 对象,并具有前置初始化,使用常量表达式初始化,或

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


a 是一个常量表达式吗?

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


一个 glvalue 整数常量表达式是常量表达式吗? 不是,为了使其成为整数常量表达式,必须将其转换为 prvalue,因此不能是 glvalue。

核心常量表达式在转换之前是整数常量表达式,还是在转换之后是整数常量表达式? - stackcpp
@stackcpp 所以这些都是特定表达式的上下文,因此常量表达式是“条件表达式”,因此您要查找语法中出现“条件表达式”或“常量表达式”的位置。 - Shafik Yaghmour
我的原始想法是 const int a = 1;//a 有自动存储期,根据 5.20p5,常数表达式中,glvalue 核心的常数表达式所指向的对象必须具有静态存储期。所以 a 不是常数表达式,但它可以用作数组边界,因此它是整数常量表达式。这很奇怪。整数常量表达式不是常量表达式。一定有地方出错了,但我找不到。 - stackcpp
请看我的新问题:http://stackoverflow.com/questions/31537359/const-int-a-1-is-a-a-constant-expression-if-a-has-automatic-storage-du - stackcpp
int b[a]{}; 的语境中,'a' 是一个常量表达式。但是在 int &b = a; 的语境中,'a' 不是一个常量表达式。 - stackcpp
显示剩余5条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接