提问者:小点点

` const int a = 1;如果‘a’有自动存储持续时间,那么‘a’是常数表达式吗


n 4527 5.20[表达式常数]p2

条件表达式 e 是核心常量表达式,除非按照抽象机器 (1.9) 的规则对 e 进行计算,否则将计算以下表达式之一:

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

(2 . 7 . 1)-整数或枚举类型的非易失性glvalue,它引用一个完整的非易失性const对象,该对象具有一个在先初始化,用常量表达式初始化,或

(2.7.2) — 引用字符串文本 (2.13.5) 的子对象的非易失性 gl值,或

(2.7.3)-非易失性glvalue,指用constexpr定义的非易失对象,或指此类对象的不可变子对象,或

(2.7.4) — 文字类型的非易失性 gl值,指的是其生命周期始于 e 评估的非易失性对象;

5.20[expr.const]p5

常量表达式是一个glvalue核心常量表达式,其值引用的实体是常量表达式(定义如下)的允许结果,或者是一个prvalue核心常量表达,其值是一个对象,对于该对象及其子对象:

— 引用类型的每个非静态数据成员都引用一个实体,该实体是常量表达式的允许结果,并且

-如果对象或子对象是指针类型,则它包含具有静态存储持续时间的对象的地址、超过该对象结尾的地址(5.7)、函数的地址或空指针值。

如果实体是具有静态存储持续时间的对象,不是临时对象,或者是其值满足上述约束的临时对象,或者它是一个函数,则该实体是常量表达式的允许结果。

void foo(){
    const int a = 1;//a has automatic storage duration
    int b[a]{};
}

intb[a]{}a是一个id表达式,a

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


共1个答案

匿名用户

可以是prvalue核心常量表达式,但不能是glvalue核心常量,这也不可能。你已经在标准中找到了措辞,所以也许最好解释一下为什么规则是这样的。

void foo(){
    const int a = 1;//a has automatic storage duration
    static constexpr const int &ra = a;// cannot possibly be valid
}

这是无效的,因为它要求在调用foo之前知道a的地址,然后才有任何a

你的int b[a]{};很好,因为它使用a作为prvalue核心常量表达式:它不关心a存储在哪里,它只关心它有什么值。