milanHrabos
milanHrabos

Reputation: 1965

Why is brace-initialization not needed with array of struct?

This code:

#include <stdio.h>

struct
{
    int i;
    const char* str;
} ar[] = {
    1,"asd", //should be {1, "asd"},
    2, "qwe", //should be {2, "qwe"},
    3, "poi" //should be {3,"poi"}
};

int main()
{
    printf("%s\n", ar[2].str);
}

Works perfectly fine, even though each element of array ar should enclosed in braces (I would expect that at least). Why is this possible?

Upvotes: 6

Views: 886

Answers (2)

P.P
P.P

Reputation: 121407

6.7.9 Initialization/20 states how such struct elements are initialized:

[..] If the initializer of a subaggregate or contained union begins with a left brace, the initializers enclosed by that brace and its matching right brace 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.

(emphasis mine)

So it's valid. And thus

ar[] = {
    1,"asd",
    2, "qwe",
    3, "poi"
};

is equivalent to:

 ar[] = {
    {1,"asd"},
    {2, "qwe"},
    {3, "poi"}
};

and ar contains 3 elements.

Upvotes: 4

klutt
klutt

Reputation: 31409

It's possible for the very simple reason that the standard allows it.

So why does the standard allow it? Well, I don't know if there's any rationale behind this. The most likely reason is that it's simply because of backwards compatibility. The C language is literary full of such things.

However, it is considered bad style. So avoid it. And if you compile with warnings enabled, which you shall do, you get this warning:

warning: missing braces around initializer [-Wmissing-braces]
    7 | } ar[] = {
      |          ^
    8 |     1,"asd", //should be {1, "asd"},
      |     {      }
    9 |     2, "qwe", //should be {2, "qwe"},
      |     {       }
   10 |     3, "poi" //should be {3,"poi"}
      |     {
   11 | };
      | }

And the philosophy behind C is very different compared to many other languages. One could argue that even if it's bad style to omit the braces, there is not really a reason to forbid omitting them. For instance, it does not cause any ambiguity.

Upvotes: 2

Related Questions