Search code examples
c++multidimensional-arrayinitializationdeclarationc++20

Initializing a multi-dimensional array in C++ 20 using an expression list


Is it correct such an initialization of a multi-dimensional array in C++ 20 using an expression list?

int a[][3]( 1, 2, 3, { 4, 5, 6 } );

At least the C++ compiler of MS VS 2019 does not compile such a declaration

This declaration

int a[][3]( 1, 2, 3, 4, 5, 6 );

is not also compiled while this declaration

int a[][3]( { 1, 2, 3 }, { 4, 5, 6 } );

is compiled successfuly.

In the corresponding quote from the C++ 20 Standard (9.4 Initializers) relative to array initialization there is nothing said about whether brace elision is allowed or not when an expression list is used.

(17.5) — Otherwise, if the destination type is an array, the object is initialized as follows. Let x1, . . . , xk be the elements of the expression-list. If the destination type is an array of unknown bound, it is defined as having k elements. Let n denote the array size after this potential adjustment. If k is greater than n, the program is ill-formed. Otherwise, the ith array element is copy-initialized with xi for each 1 ≤ i ≤ k, and value-initialized for each k < i ≤ n. For each 1 ≤ i < j ≤ n, every value computation and side effect associated with the initialization of the ith element of the array is sequenced before those associated with the initialization of the jth element.


Solution

  • Rereading the provided quote especially its this part

    the ith array element is copy-initialized with xi for each 1 ≤ i ≤ k

    It seems that such an initialization like this

    int a[][3]( 1, 2, 3, { 4, 5, 6 } );
    

    is indeed incorrect because the element of the array a is in turn an array of the type int[3] and to initialize it in this case you need to use a braced-init-list. After that within the braced-init-list the brace elision will be accepted. That is you may not initialize an array with an expression.

    Here is an example that confirms that and is compiled by the C++ compiler of MS VS 2019

    int e[][2][3]( { 1, 2, 3,  { 4, 5, 6 } }, { 6, 5, 4, 3, 2, 1 } );
    

    Within the braced-init-lists the brace elision may be used.