ISO C95 数组初始化保证

Phi*_*ilC 2 c arrays string-literals language-lawyer aggregate-initialization

我试图找到确认或反驳以下声明的文件

char test[5]="";
Run Code Online (Sandbox Code Playgroud)

导致缓冲区初始化为所有与

memset(test,'\0',sizeof(test));
Run Code Online (Sandbox Code Playgroud)

但一直无法找到(或理解/破译)任何东西。我专门寻找旧规范中的细节,C99 参考也可以使用。谢谢

M.M*_*M.M 5

这不是对您问题的完整答案,而是用于澄清其他答案中的错误信息

在 ANSI C89 中,相关标准文本是(第 3.5.7 节):

如果没有显式初始化具有自动存储持续时间的对象,则其值是不确定的。

字符类型的数组可以由字符串文字初始化,可选地括在大括号中。字符串文字的连续字符(如果有空间或数组大小未知,则包括终止空字符)初始化数组的成员。

它只指定与字符串文字对应的数组元素的初始化。因此,尾随数组元素未显式初始化,因此具有不确定的值。

还有一段话:

如果列表中的初始值设定项少于聚合的成员数,则聚合的其余部分应与具有静态存储持续时间的对象隐式初始化相同。

但这并不适用,因为我们不是从列表初始化(“列表”表示括号括起来的列表,而不是字符串文字)。


在 C90(我不确定我是否可以合法地链接到它)中,这些部分被重新编号,以便包含这些段落的部分变成 6.5.7。后一段的措辞也发生了变化:

如果花括号括起来的列表中的初始值设定项少于聚合的成员数,则聚合的其余部分应隐式初始化,与具有静态存储持续时间的对象相同。


在 C90 TC1 ( HTML , PDF ) 中,上述内容没有改变。

然而,在缺陷报告 60 中,提出了一个关键问题:

当一个字符数组(或 wchar_t)用包含比数组更少字符的字符串文字初始化时,数组的剩余元素是否被初始化?

第 72 页的第 6.5.7 节初始化只说(强调我的):

如果花括号括起来的列表中的初始值设定项少于聚合的成员数,则聚合的其余部分应隐式初始化,与具有静态存储持续时间的对象相同。

更正

在第 72 页的第 6.5.7 节中,语义的倒数第二段(在示例之前),在逗号后添加:

用于初始化已知大小数组的字符串文字或宽字符串文字中的或更少的字符,以及字符或 wchar_t 类型的元素

似乎建议修复中的零初始化确实是标准编写者的意图,因为在C90 TC2 中,我们看到了相同的关键更改:

第 72 页

在第 72 页的第 6.5.7 节中,语义的倒数第二段(在示例之前),在逗号后添加:

用于初始化已知大小数组的字符串文字或宽字符串文字中的或更少的字符,以及字符或 wchar_t 类型的元素

给我们:

如果花括号括起来的列表中的初始值设定项少于聚合的成员数,或者用于初始化已知大小数组的字符串文字或宽字符串文字中的字符更少,并且字符或 wchar_t 的元素键入剩余部分聚合应与具有静态存储持续时间的对象一样隐式初始化。

请注意,TC1 的日期是 1994 年,尽管它是在 1995 年发布的。TC2 的日期是 1996 年。令人困惑的是,DR60 的日期是 1993 年 7 月 16 日,因此早于 TC1。也许到那时 TC1 的工作太先进了,无法处理新的缺陷报告和积压的积压?在任何情况下,TC2 主要只是针对缺陷报告的一组更正,这表明更改首先出现在那里而不是在 C95 中,并且空终止符之后的字符零初始化是 C89 标准编写者所拥有的故意的。


在 ISO C99(原始版本,没有技术勘误表)中,该段落现在重新编号为 6.7.8/21 并再次更改。删除了“宽字符串文字”“字符或 wchar_t 类型元素的提及:

如果花括号括起来的列表中的初始值设定项少于聚合的元素或成员,或者用于初始化已知大小数组的字符串文字中的字符少于数组中的元素,则聚合的其余部分应隐式初始化与具有静态存储持续时间的对象相同。

这意味着尾随数组元素被初始化为空字节。

注意:原始 C99 可能是受版权保护的材料,因此我无法在上面发布指向它的链接。不过,它就是这么说的。是指向最后一个免费提供的工作草案的链接。还有两个草案在那之后,但WG14网站已将其删除。不过,该措辞在N843工作草案中,并且仍然存在于后来包含TC3的C99中。


我一直找不到 C95 (ISO/IEC 9899:1990/AMD1:1995) 的任何免费副本。因此,我无法回答“宽字符串文字”和“wchar_t”更改在 C89 和 C99 之间的确切点。此外,C99 基本原理文档中未提及该主题。

当然,C99 的行为可能是 C89 作者的意图,缺少的文本是一个疏忽,但由于没有任何类型的文档,我们无法得出任何结论,并且可能有编译器来自那个时候不初始化尾随元素。

希望拥有这些文件的其他人(或倾向于从 ISO 商店购买它们!)可以提供准确的答案。

  • @KeithThompson 好的,那就太好了。当然,除非他们记录下来,否则我们无法知道他们的意图,因此我们必须将文本的字母作为指定的行为(更重要的是,编译器供应商可能会这样做)。我确实记得在 clc 时代之前讨论过这个问题,甚至可能在 C99 发布之前,也许是因为人们观察到编译器没有初始化尾随元素。这些档案中可能有一些相关的内容 (2认同)