问题描述
下面的C ++ 11程序是否错误?
const int x [] = {1,2, 3};
static_assert(x [0] == 1,yay);
int main(){}
gcc和clang似乎认为,但是为什么 x [0] == 1
是一个常量表达式?
x [0] == 1
下标运算符
*(x + 0)== 1
数组到指针的转换(int * p = x)
*(p + 0)== 1
指针添加
* p == 1
间接(l值y = x [0])
y == 1
左值到右值转换:
似乎为真,<$ c的第一个元素$ c> x 数组符合这些条件。
1 == 1
?
这是一个编译器错误,标准缺陷我缺少一些东西?
5.19 [expr.const]的哪一部分说这不是一个常量表达式?
解决方案在5.19中:
很明显,左值到右值转换只能在常量表达式中进行,如果:
- 用常量初始化的常量整数(或枚举)声明:
const int x = 3;
li>
- 一个包含
constexpr
的声明: constexpr int x [] = {1,2,3};
。
- 用常量表达式初始化的临时对象...
您的示例包括lvalue-to-rvalue转换,但没有这些异常,因此 x
不是常量表达式。然而,如果你把它改成:
constexpr int x [] = {1,2,3}
static_assert(x [0] == 1,yay);
int main(){}
p>
Is the following C++11 program ill-formed?
const int x[] = {1,2,3};
static_assert(x[0] == 1, "yay");
int main() {}
gcc and clang seem to think so, but why isn't x[0] == 1
a constant expression?
x[0] == 1
subscript operator
*(x+0) == 1
array-to-pointer conversion (int* p = x)
*(p+0) == 1
pointer addition
*p == 1
indirection (lvalue y = x[0])
y == 1
lvalue-to-rvalue conversion:
Seems true, the first element of the x
array satisfies these conditions.
1 == 1
?
Is this a compiler bug, standard defect, or am i missing something?
What part of 5.19 [expr.const] says this isn't a constant expression?
解决方案 In 5.19:
Putting it plainly, lvalue-to-rvalue conversion can only be done in constant expressions if:
- a constant integral (or enum) declaration initialized with a constant:
const int x = 3;
. - a declaration with
constexpr
: constexpr int x[] = {1,2,3};
. - a temporary object initialized with a constant expression...
Your example does include lvalue-to-rvalue conversion, but has none of these exceptions, so x
is not a constant expression. If, however, you change it to:
constexpr int x[] = {1,2,3};
static_assert(x[0] == 1, "yay");
int main() {}
Then all is well.
这篇关于`x [0] == 1`在C ++ 11中的常量表达式,当x是const int []?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!