【问题标题】:Why is brace-initialization not needed with array of struct?为什么结构数组不需要大括号初始化?
【发布时间】:2021-03-25 12:54:46
【问题描述】:

这段代码:

#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 就是这样做的,而标准 C 必须尽可能使用准标准源代码。
  • 从来不知道。很棒的发现。

标签: c curly-braces list-initialization


【解决方案1】:

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

[..] 如果子聚合或包含联合的初始化程序开始 使用左大括号,由该大括号括起来的初始化器及其 匹配右大括号初始化元素或成员 子聚合或包含的联合。否则,就够了 列表中的初始化器被考虑到元素或 子聚合的成员或包含的第一个成员 联盟;剩下的任何初始化器都留给初始化下一个 当前子聚合所在的聚合的元素或成员 或包含的联合是一部分。

强调我的

所以它是有效的。因此

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

相当于:

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

ar 包含 3 个元素。

【讨论】:

    【解决方案2】:

    标准允许这样做的原因很简单。

    那么为什么标准允许它呢?好吧,我不知道这背后是否有任何理由。最可能的原因是这仅仅是因为向后兼容。 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 背后的哲学非常不同。有人可能会争辩说,即使省略括号是一种不好的风格,也没有真正的理由禁止省略它们。例如,它不会引起任何歧义。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-07-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-06-30
      • 2016-04-14
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多