例如,如果 somestruct
有三个整数成员,我一直认为在C(或C)函数中执行此操作是可以的:
somestruct s = {123,};
第一个成员将初始化为123,最后两个成员将初始化为0.我经常对自动数组执行相同操作,编写 int arr[100] = {0,};
以便将数组中的所有整数初始化为零 .
最近我在GNU C Reference Manual中读到:
如果未初始化结构变量,则效果取决于它是否具有静态存储(请参阅存储类说明符) . 如果是,则使用0初始化具有整数类型的成员,并将指针成员初始化为NULL;否则,结构成员的 Value 是不确定的 .
有人可以告诉我关于部分自动结构和自动阵列初始化的C和C标准吗?我在Visual Studio中执行上面的代码没有问题,但我希望与gcc / g兼容,也可能与其他编译器兼容 . 谢谢
5 回答
链接的gcc文档没有谈到 Partial Initialization 它只是谈到 (Complete)Initialization 或 No Initialization .
标准没有定义对象的部分初始化,要么是完全初始化,要么是无初始化 . 部分初始化是一种非标准术语,通常指的是您提供一些初始值设定项但不是全部的初始值,即:初始化程序的数量少于数组的大小或初始化的结构元素的数量 .
例:
初始化意味着在创建变量的同时为创建的变量提供一些初始值 . 即:在相同的代码声明中 .
例:
引用的段落描述了
Case 3
的行为 .有关部分初始化(
Case 1
)的规则由标准很好地定义,并且这些规则不依赖于正在初始化的变量的存储类型 .AFAIK,所有主流编译器都100%遵守这些规则 .
C和C标准保证即使整数数组位于自动存储上,并且如果括号括起的列表中的初始化程序较少,则未初始化的元素 must 也会初始化为
0
.C99 Standard 6.7.8.21
在C中,规则的陈述略有不同 .
C++03 Standard 8.5.1 Aggregates
Para 7:
在定义值初始化时,
C++03 8.5 Initializers
Para 5:
最新的gcc版本也允许同时“部分”初始化和zeromem:
struct成员现在将具有以下值:
a=0, b=5, c=0
我没有关于其他编译器是否允许这样做的任何信息:p
在C中,对象永远不会被部分初始化 - 如果它们的任何部分被初始化,则初始化整个对象(以及递归的所有子对象) . 如果未提供显式初始化器,则元素初始化为"zero of the appropriate type" .
您的问题中的引用是指完全省略整个对象的初始化程序,而不是指子对象缺少初始化程序时 . 例如,假设
arr
具有自动存储持续时间,那么:将
arr[0]
初始化为123
,将arr
的每个其他元素初始化为0
. 鉴于此:留下
arr
未初始化的每个元素 . 引用的是后一种情况 .如果变量是全局变量和静态变量,则它在二进制文件的全局区域中分配,该区域被初始化为零 . 如果变量是本地的,它在堆栈中分配,编译器不会初始化堆栈中的内存 . (某些调试版本可能会初始化,但发布版本永远不会这样做)
如果变量是在Heap中分配的,则编译器也不会对其进行初始化 .