c - ISO C95 数组初始化保证
问题描述
我试图找到确认或反驳以下声明的文件
char test[5]="";
导致一个缓冲区初始化为所有相同的空字符
memset(test,'\0',sizeof(test));
但无法找到(或理解/破译)任何东西。我专门在旧规范中寻找细节,C99 参考也可以。谢谢
解决方案
这不是您问题的完整答案,但有助于清除其他答案中的错误信息。
在 ANSI C89 中,相关的标准文本是(第 3.5.7 节):
如果具有自动存储持续时间的对象未显式初始化,则其值是不确定的。
字符类型的数组可以由字符串字面量初始化,可选地用大括号括起来。字符串文字的连续字符(如果有空间或数组大小未知,则包括终止的空字符)初始化数组的成员。
它仅指定与字符串文字对应的数组元素的初始化。所以尾随数组元素没有显式初始化,因此具有不确定的值。
还有一段话:
如果列表中的初始化程序少于聚合的成员,则聚合的其余部分应隐式初始化,与具有静态存储持续时间的对象相同。
但这并不适用,因为我们不是从列表中初始化的(“列表”表示用大括号括起来的列表,而不是字符串文字)。
在 C90(我不确定是否可以合法链接到)中,这些部分被重新编号,因此包含这些段落的部分变为 6.5.7。后一段的措辞也发生了变化:
如果大括号括起来的列表中的初始化程序少于聚合的成员,则聚合的其余部分应隐式初始化,与具有静态存储持续时间的对象相同。
在 C90 TC1 ( HTML , PDF ) 中,上述内容保持不变。
然而,在缺陷报告 60中,提出了一个关键问题:
当 char(或 wchar_t)数组使用包含的字符数少于数组的字符串字面量进行初始化时,数组的其余元素是否已初始化?
子条款 6.5.7 初始化,第 72 页,只说(强调我的):
如果大括号括起来的列表中的初始化程序少于聚合的成员,则聚合的其余部分应隐式初始化,与具有静态存储持续时间的对象相同。
更正
在第 72 页的 6.5.7 小节中,语义的倒数第二段(在示例之前),在逗号之后添加:
用于初始化已知大小数组的字符串文字或宽字符串文字中的或更少字符,以及 character 或 wchar_t 类型的元素
看来,建议修复中的零初始化确实是标准编写者的意图,因为在C90 TC2中,我们看到了同样的关键更改:
第 72 页
在第 72 页的 6.5.7 小节中,语义的倒数第二段(在示例之前),在逗号之后添加:
用于初始化已知大小数组的字符串文字或宽字符串文字中的或更少字符,以及 character 或 wchar_t 类型的元素
给我们:
如果大括号括起来的列表中的初始化程序少于聚合的成员,或者用于初始化已知大小的数组的字符串文字或宽字符串文字中的字符更少,并且字符或 wchar_t 的元素类型的其余部分聚合应隐式初始化,与具有静态存储持续时间的对象相同。
请注意,TC1 的日期是 1994 年,尽管它是在 1995 年出版的。TC2 的日期是 1996 年。令人困惑的是,DR60 的日期是 1993 年 7 月 16 日,因此早于 TC1。也许那时 TC1 的工作已经太先进了,无法处理新的缺陷报告并且积压了?在任何情况下,TC2 大多只是针对缺陷报告的一组更正,表明该更改首先出现在 C95 中而不是在 C95 中,并且空终止符之后字符的零初始化是 C89 标准编写者所拥有的故意的。
在 ISO C99(原始版本,没有技术勘误)中,该段落现在重新编号为 6.7.8/21 并再次更改。删除了“宽字符串文字”和“字符或 wchar_t 类型的元素”的提及:
如果大括号括起来的列表中的初始化程序少于聚合的元素或成员,或者用于初始化已知大小数组的字符串文字中的字符少于数组中的元素,则聚合的其余部分应隐式初始化与具有静态存储持续时间的对象相同。
意味着尾随数组元素被初始化为空字节。
(注意:原始的 C99 可能是受版权保护的材料,所以我不能在上面发布指向它的链接。不过,这就是它所说的。这是最后一个免费可用的工作草稿的链接。还有两个草稿之后,但 WG14 网站已将其删除。不过,该措辞在 N843 工作草案中,并且仍然存在于后来合并 TC3 的 C99 中。)
我一直找不到任何 C95 (ISO/IEC 9899:1990/AMD1:1995) 的免费副本。因此,我无法准确回答在 C89 和 C99 之间的哪个点进行了“宽字符串文字”和“wchar_t”更改。此外,C99 基本原理文档中未提及该主题。
当然,C99 的行为可能是 C89 作者的意图,而缺少的文本是疏忽,但是在没有任何类型的文档的情况下,我们无法得出任何结论,并且可能有来自的编译器那个时候不初始化尾随元素。
希望其他拥有这些文件(或倾向于从 ISO 商店购买它们!)的人可以提供准确的答案。
推荐阅读
- android - 在我的 libgdx 项目中,如何修复:“错误:没有为属性 'manifestOutputDirectory' 指定值。”?
- java - 供应 id 的 Java 返回文章库
- python - 如何在jupyter笔记本中执行eof
- python - 用python将句子列表拆分为单词列表
- java - 切换按钮元素消失但动画完成后突然重新出现
- java - 如何将字符串值转换为数字
- c++ - 如何在我的代码中找到(并删除)需要管理员权限的位置?
- google-sheets - 使工作表在指定单元格中输入行号
- laravel - 我最近在我的 laravel 项目中使用了 JCrop,但是虽然我选择了一张照片并加载了它,但我得到了验证错误 image is requred
- material-ui - const primary = red[500]; 之间有什么不同?// #F44336 const 重音 = red['A200']; // #F44336?