Why is it really C

I came across this code on reddit . I would have thought that type conversions would make this invalid.

int a[3] = { { {1, 2}, {3, 4}, 5, 6 }, {7, 8}, {9}, 10 }; 

In clang, I get a few warnings about excessive elements and curly braces in a scalar initializer. But the content of a is [1, 7, 9] .

This is really legal, and if so, can someone explain what exactly is happening?

+47
c
Mar 20 '12 at 17:44
source share
2 answers

Elements of excess are simply ignored. There are two parts to 6.7.8 The initialization you care about. First, from paragraph 17:

Each initializer list, enclosed in braces, has a current object associated with it. When there is no designation, the subobjects of the current object are initialized in the order corresponding to the type of the current object: array elements in ascending index order, structure members in the declaration order, and the first named member of the union.

This explains why you get 1, 7, and 9 — the current object is set by these curly braces. Then, why he does not care about additional things, from paragraph 20:

... only a sufficient number of initializers from the list are taken into account for elements or members of a sub-aggregate or the first member of a joint union; any remaining initializers are left to initialize the next element or member of the population, of which the current sub-aggregate or containing the union is a part.

+28
Mar 20 '12 at 17:45
source share
  int a[3] = { { {1, 2}, {3, 4}, 5, 6 }, {7, 8}, {9}, 10 }; 

wrong.

Not valid for the same reasons int b[1] = {1, 2}; is invalid: as C99 says

(C99, 6.7.8p1) "No initializer will attempt to provide a value for an object not contained in the initialized object."

The last element 10 in a initializers is trying to provide a value for an object not contained in the initialized object.

+2
Jun 28 '13 at 15:22
source share



All Articles