[dcl.dcl]/1 (final C++17 draft, N4659) describe the grammar of a simple-declaration as:
[...]
simple-declaration: - [...] - attribute-specifier-seq(opt) decl-specifier-seq ref-qualifier(opt) [ identifier-list ] initializer;
[dcl.dcl]/8 describes that the latter form of a simple-declaration is a structured binding declaration:
A simple-declaration with an identifier-list is called a structured binding declaration ([dcl.struct.bind]). The decl-specifier-seq shall contain only the type-specifier
autoand cv-qualifier:s. The initializer shall be of the form “= assignment-expression”, of the form “{ assignment-expression }”, or of the form “( assignment-expression )”, where the assignment-expression is of array or non-union class type.
I.e., for the purpose of this question, a structured binding have the simplified grammar:
auto[ identifier-list ] initializer ;
where any of the following forms are valid initializer:s:
... = assignment-expression
... { assignment-expression }
... ( assignment-expression )
Thus, arguably the following code is well-formed:
struct S { int s; };
int main() {
const S s{42};
const int arr[1] = {42};
// ... of the form “= assignment-expression”
auto[s_form1] = s;
auto[e_form1] = arr;
// ... of the form “{ assignment-expression }”
auto[s_form2]{s};
auto[e_form2]{arr};
// ... of the form “( assignment-expression )”
auto[s_form3](s);
auto[e_form3](arr);
(void)s_form1; (void)s_form2; (void)s_form3;
(void)e_form1; (void)e_form2; (void)e_form3;
return 0;
}
Using both -std=c++17 and -std=c++2a, GCC (9.3) accepts this code whereas clang (10.0.0 as well as HEAD/11) rejects the "{ assignment-expression }" form for arrays:
auto[e_form2]{arr}; ^~~ error: cannot initialize an array element of type 'const int' with an lvalue of type 'const int [1]'
It fails likewise for an rvalue array:
using SingleElementIntArray = int[1]; auto[e_form2]{SingleElementIntArray{42}}; ^~~~~~~~~~~~~~~~~~~~~~~~~ error: cannot initialize an array element of type 'int' with an rvalue of type 'SingleElementIntArray' (aka 'int [1]')
Question
- Who is right here, GCC or clang? My guess is GCC; if so, is this a known clang bug?