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

2

6

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?

Intradermal answered 25/3, 2021 at 12:54 Comment(2)
Backwards compatibility. Because pre-standard C did it that way, and standard C had to work with pre-standard source whenever possible.Alpers
Never knew that. Great find.Kareenkarel
C
4

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.

Chinch answered 25/3, 2021 at 13:38 Comment(0)
L
2

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.

Lapith answered 25/3, 2021 at 13:1 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.