为什么结构数组不需要大括号初始化?

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

此代码:

#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);
}

工作得很好,即使数组 ar 的每个元素都应该用大括号括起来(我至少希望如此)。为什么这可能?

这是可能的,原因很简单,因为标准允许。

那么为什么标准允许呢?好吧,我不知道这背后是否有任何理由。最可能的原因是它仅仅是因为向后兼容。 C语言充满了文学气息

然而,它被认为是糟糕的风格。所以避免它。如果你在启用警告的情况下编译,你 应该 这样做,你会收到这个警告:

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 | };
      | }

C 背后的哲学与许多其他语言相比有很大不同。有人可能会争辩说,即使省略大括号是不好的风格,也没有真正禁止省略它们的理由。例如,它不会引起任何歧义。

6.7.9 Initialization/20 说明如何初始化这些结构元素:

[..] 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.

(强调我的)

所以它是有效的。因此

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

相当于:

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

ar包含3个元素。