Structured binding initializer form { assignment-expression } fails for array type on clang

Viewed 88

[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 auto and 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?
1 Answers

This is a known bug, with an open bug report

LLVM open bug report:

Ryou Ezoe 2017-03-30 00:24:07 PDT:

Clang doesn't support structured binding of initializer form {" expr }" if expr is id-expression of array object. Clang does not accept following code.

int expr[] = { 1,2,3 } ;
auto [a,b,c]{expr} ;

with the error:

prog.cc:4:18: error: cannot initialize an array element of type 'int' with an lvalue of type 'int [3]'

Other cases are works as expected. "( expr )" works as well as "{ expr }" where expr is id-expression of class object:

auto [a,b,c](expr) ;

struct X { int x,y,z } ; 
X x {1,2,3} ; 
auto [a,b,c]{ x } ;
Related