【发布时间】:2015-10-10 03:40:26
【问题描述】:
N4527 5.20[expr.const]p5
一个常量表达式要么是一个泛左值核心常量表达式,它的值是指一个实体,它是一个 常量表达式(如下定义)或纯右值核心常量表达式的允许结果,其 value 是一个对象,对于该对象及其子对象:
——每个引用类型的非静态数据成员引用一个实体,它是一个常量表达式的允许结果,并且
—如果对象或子对象是指针类型,则它包含具有静态存储持续时间的对象的地址、经过此类对象末尾的地址 (5.7)、函数的地址或空指针值.
如果一个实体是一个具有静态存储持续时间的对象,该对象要么不是临时对象,要么是其值满足上述约束的临时对象,或者它是一个 函数。
void foo(){
int a = 1;
int b[a || 1]{};//ok in gcc 5.1.0, error in clang 3.8.0
static_assert(a || 1,"");//ok in gcc 5.1.0, error in clang 3.8.0
switch(1){
case a || 1://ok in gcc 5.1.0, error in clang 3.8.0
;
}
}
a || 1 是常量表达式吗?
N4527 5.20[expr.const]p2
条件表达式 e 是核心常量表达式,除非 e 的求值遵循 抽象机器(1.9),将评估以下表达式之一:
(2.7) — 左值到右值的转换 (4.1),除非它应用于
(2.7.1) — 整数或枚举类型的非易失性左值,指的是完整的非易失性常量 具有前面初始化的对象,用常量表达式初始化,或
(2.7.2) — 非易失性泛左值,它引用字符串字面量 (2.13.5) 的子对象,或
(2.7.3) — 一个非易失性泛左值,它引用一个用 constexpr 定义的非易失性对象,或者引用 到此类对象的非可变子对象,或
(2.7.4) — 文字类型的非易失性左值,它引用一个生命周期开始的非易失性对象 在e的评价范围内;
a || 1 是核心常量表达式吗?
【问题讨论】:
-
AFAIK GCC 具有“可变长度数组”功能 (gcc.gnu.org/onlinedocs/gcc/Variable-Length.html),它可能负责
int b[a || 1]的工作。不过,我知道的还不够多,无法正确回答您的问题。 -
引用
N4527有什么特别的理由吗?这种特殊情况对于 C++11 和 C++14 应该是相同的,尽管引号会略有不同。 -
@ShafikYaghmour 因为它是最近的,我从 github 下载。另一个关于 5.20[expr.const] 的问题,见stackoverflow.com/questions/31527913/…
-
这个问题是 C++1z 是一个移动的目标,所以措辞可能会发生变化。而在 C++11/14 中,它们已经完成,据我所知,更改只能通过缺陷报告应用,虽然并不完美,但它们在某种程度上是自我记录的。 C++11/14 也是人们在生产中使用的(可能主要是 C++11),因此更相关,恕我直言。对于这个问题,据我所知,其他问题的答案是相同的,尽管引号将针对特定标准。
标签: c++ language-lawyer constant-expression c++17