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:
a non-volatile glvalue (yes, x[0] is a glvalue and non-volatile) of integral (yes it has type const int) or enumeration type that refers to a non-volatile const object (yes it has type const int) with a preceding initialization (yes initialized with 1), initialized with a constant expression (yes 1 is constant expression)
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?
x[0]
has integral type so the lvalue-to-rvalue conversion should be allowed, but it still isn't. – Andrew Tomazosconstexpr
has always been required to use a constant array element as a compile-time constant. You can't use a constant array element as acase
or as a template parameter either, unless you useconstexpr
, and I believe this is considered normal. Maybe you've found a place where the spec mis-specifies this behavior? – StilesCrisis