猿问

C和C ++:自动结构的部分初始化

C和C ++:自动结构的部分初始化

例如,如果somestruct有三个整数成员,我一直认为在C(或C ++)函数中执行此操作是可以的:

somestruct s = {123,};

第一个成员将初始化为123,最后两个成员将初始化为0.我经常对自动数组执行相同的操作,写入int arr[100] = {0,};以便将数组中的所有整数初始化为零。


最近我在GNU C参考手册中读到:

如果不初始化结构变量,则效果取决于它是否具有静态存储(请参阅存储类说明符)。如果是,则使用0初始化具有整数类型的成员,并将指针成员初始化为NULL; 否则,结构成员的价值是不确定的。


有人可以告诉我C和C ++标准对部分自动结构和自动数组初始化的看法吗?我在Visual Studio中执行上述代码没有问题,但我希望与gcc / g ++兼容,也可能与其他编译器兼容。谢谢


潇潇雨雨
浏览 548回答 3
3回答

慕后森

链接的gcc文档没有谈到部分初始化它只谈到(完成)初始化或没有初始化。什么是部分初始化?标准没有定义对象的部分初始化,要么是完全初始化,要么是无初始化。部分初始化是一种非标准术语,通常指的是您提供一些初始化器但不是全部的情况,即:初始化器的数量少于阵列的大小或初始化的结构元素的数量。例:int array[10] = {1,2};                    //Case 1:Partial Initialization什么是(完整)初始化或无初始化?初始化意味着在创建变量的同时为创建的变量提供一些初始值。即:在相同的代码语句中。例:int array[10] = {0,1,2,3,4,5,6,7,8,9};    //Case 2:Complete Initializationint array[10];                            //Case 3:No Initialization引用的段落描述了行为Case 3。关于部分初始化(Case 1)的规则由标准很好地定义,并且这些规则不依赖于被初始化的变量的存储类型。AFAIK,所有主流编译器都100%遵守这些规则。有人可以告诉我C和C ++标准对部分自动结构和自动数组初始化的看法吗?C和C ++标准保证即使整数数组位于自动存储上,并且如果括号括起的列表中的初始化程序较少,则必须将未初始化的元素初始化为0。C99标准6.7.8.21如果括号括起的列表中的初始值设定项少于聚合的元素或成员,或者用于初始化已知大小的数组的字符串文字中的字符数少于数组中的元素,则聚合的其余部分应为隐式初始化与具有静态存储持续时间的对象相同。在C ++中,规则的陈述略有不同。C ++ 03标准8.5.1聚合第7段:如果列表中的初始值设定项少于聚合中的成员,则未明确初始化的每个成员都应进行值初始化(8.5)。[例: struct S { int a; char* b; int c; };  S ss = { 1, "asdf" };初始化ss.awith 1,ss.bwith "asdf"和ss.cwith表达式的表达式int(),即0。]值初始化定义于,C ++ 03 8.5 Initializers Para 5:到值初始化类型的物体T是指:-如果T是一个类型(第9节)与用户声明的构造(12.1),然后对T中的默认构造函数被调用(以及初始化是形成不良的如果T没有可访问的默认构造函数); - 如果T是没有用户声明的构造函数的非联合类类型,则T的每个非静态数据成员和基类组件都是值初始化的; - 如果T是数组类型,则每个元素都是值初始化的; - 否则,对象被零初始化

aluckdog

在C中,对象永远不会被部分初始化 - 如果它们的任何部分被初始化,则初始化整个对象(以及递归的所有子对象)。如果没有提供显式初始化器,则将元素初始化为“适当类型的零”。您的问题中的引用是指完全遗漏整个对象的初始化程序,而不是指子对象缺少初始化程序时。例如,假设arr具有自动存储持续时间,那么:int arr[100] = { 123 };初始化arr[0]到123与所有其他元素arr来0。鉴于此:int arr[100];留下arr未初始化的每一个元素。引用的是后一种情况。

慕村225694

最新的gcc版本也允许同时“部分”初始化和zeromem:typedef struct{   int a,b,c;}T;T s = {0, .b=5};struct成员现在将具有以下值: a=0, b=5, c=0我没有关于其他编译器是否允许这样做的任何信息:p
随时随地看视频慕课网APP
我要回答