【问题标题】:Zero'ing an array before adding an entry在添加条目之前将数组归零
【发布时间】:2021-06-15 12:35:34
【问题描述】:

以下是否将列表清零然后添加第一个条目?还是只是将第一个条目添加到handlers

 Logger = (struct logger) {.level=INFO, .format=DEFAULT_FORMAT, .num_handlers=1, .handlers[0]=stdout};

例如,这样做:

Logger.handlers = {0};
Logger.handlers[0] = stdout;

还是不涉及清算?

【问题讨论】:

  • 如果.handlers[] 有多个元素,则.handlers[0]=stdout 和所有其他元素默认初始化为零。见:C11 Standard § 6.7.9 Initialization (p21)
  • @DavidC.Rankin 你能把它作为答案发布吗?因为还有另一个答案正好相反。另外,请注意这是一个复合文字,而不是变量初始化。但它继承了语义。
  • @Barmar 当然,请稍等,我会写下来。

标签: c compound-literals


【解决方案1】:

例如,这样做:

Logger.handlers = {0};
Logger.handlers[0] = stdout;

回答:是的(但不是按这个顺序)

C11 Standard § 6.7.9 - Initialization 部分下有三个标准部分(如果您采用专门使以下两个适用于“聚合对象”(结构和数组)的部分,则实际上是 4 个)。您的案例询问“如果在初始化期间只为 Logger.handlers[0] = stdout; 提供值,Logger.handlers 的其他元素会发生什么情况?”

要回答这个问题,您需要查看§ 6.7.9 Initialization (p19)§ 6.7.9 Initialization (p21)

第一个指定结构的初始化如何以“列表顺序”进行,"all subobjects that are not initialized explicitly shall be initialized implicitly the same as objects that have static storage duration." 因此,如果您提供的值少于所有值来完全初始化子对象,则那些未提供值的值将被初始化,就好像它们具有静态存储持续时间一样。 (具有静态存储持续时间的对象,未显式初始化,初始化为零(或NULL,视类型而定),请参阅:§ 6.7.9 Initialization (p10)

第 21 段特别涵盖了您的情况,即在大括号括起来的列表中提供的初始化程序较少 -- "all subobjects that are not initialized explicitly shall be initialized implicitly the same as objects that have static storage duration." § 6.7.9 Initialization (p21)

总而言之,Logger.handlers 的初始化实际发生的是第一个元素被初始化为stdout,而所有其他元素都被初始化为 NULL(因为stdoutFILE* 类型的指针) .所以你实际拥有的是:

Logger.handlers[CONST] = { stdout, NULL, NULL, ... };

仔细阅读(阅读所有§ 6.7.9),如果您还有其他问题,请告诉我。

【讨论】:

  • 感谢您。天哪,该规范读起来像是面向机器的,并且具有如此陌生的语法……
  • 有几个部分让你摸不着头脑。但是你会及时适应它们。其中一个“不太清晰”的部分与严格别名规则有关,C11 Standard - §6.5 Expressions (p6,7) .... 祝你好运...:)
【解决方案2】:

后者Logger.handlers[0] = stdout;。这就是为什么 API 有一个 .num_handlers 字段来告诉被调用代码知道有多少处理程序是有效的。

【讨论】:

  • @Allen -- 好吧,我写了那个代码,所以我不太确定你是否可以信任它。添加了.num_handlers 以使清理更容易。
  • 另一个选项是让处理程序以一个神奇的值(即 NULL)结束列表。类似于字符串由 '\0' 终止或可以是带有 char * 和 len 的结构。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-09-05
  • 1970-01-01
  • 2011-02-03
  • 1970-01-01
相关资源
最近更新 更多