Search code examples
carraysmultidimensional-arrayinitializationlanguage-lawyer

Is it standard-compliant to initialize a 2D array of unkown size by an 1D array initializer?


I recently came around this question where we got a 2D array definition like this one:

int x[][3] = { 0, 1, 2, 3, 4, 5 };

The first dimension is empty/size of the array is unknown. The array z is initialized by a 1D array initializer.

Now, this is what the C standard says (emphasize mine):

"If the aggregate or union contains elements or members that are aggregates or unions, these rules apply recursively to the subaggregates or contained unions. If the initializer of a subaggregate or contained union begins with a left brace, the initializers enclosed by that brace and its matching rightbrace initialize the elements or members of the subaggregate or the contained union. Otherwise, only enough initializers from the list are taken to account for the elements or members of the subaggregate or the first member of the contained union; any remaining initializers are left to initialize the next element or member of the aggregate of which the current subaggregate or contained union is a part.

Source: ISO/IEC 9899:2018 (C18), §6.7.9/20.

This means it is well-defined to initialize a 2D array of known amount of elements with a 1D array initializer.

Thus, f.e.:

int y[2][3] = { 0, 1, 2, 3, 4, 5 };

should be equivalent to:

int y[2][3] = { { 0, 1, 2 } , { 3, 4, 5 } };

What I am worry about is this:

"If an array of unknown size is initialized, its size is determined by the largest indexed element with an explicit initializer. The array type is completed at the end of its initializer list."

Source: ISO/IEC 9899:2018 (C18), §6.7.9/22.

It means that if the size of the array/ the amounts of elements within it is unknown, it requires that the 2D array:

  1. Needs to have an largest indexed element, and
  2. This element needs to have an explicit initializer.

My questions:

  • Is that provided here?

  • Is it standard-compliant to initialize a two-dimensional array of unkown size by an one-dimensional array initializer?

IMHO and after my actual stand of knowledge, it shouldn't. But maybe I misunderstand something here.


I opened this question because the other question is tagged with C and C++, so it is not real language lawyer appropriate and not focuses on C, plus the question of other question is actually quite different.


Solution

  • Per C 2018 6.7.9 20:

    • x of int x[][3] is being initialized. It contains an element that is an aggregate, x[0], which is an int [3].
    • The first initializer for this subaggregate is 0. It does not begin with a brace. So “only enough initializers from the list are taken to account for the elements or members of the subaggregate…”. Thus three initializers, 0, 1, and 2, are taken to initialize x[0].
    • Then “any remaining initializers are left to initialize the next element…”. So 4 and 5 are left to initialize x[1].
    • Again, 4 does not begin with a brace, so 4 and 5 are taken to initialize x[1]. Per paragraph 21, since there are not enough initializers to initialize x[1], “the remainder of the aggregate shall be initialized implicitly the same as objects that have static storage duration.”

    4 and 5 are explicit initializers. They initialize x[1]. Therefore, x[1] has an explicit initializer. It is the largest indexed element of x that has an explicit initializer. Therefore it determines the size of x.