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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/10828294/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-27 14:30:49  来源:igfitidea点击:

C and C++ : Partial initialization of automatic structure

c++c

提问by loop

For example, if somestructhas three integer members, I had always thought that it was OK to do this in C (or C++) function:

例如,如果somestruct有三个整数成员,我一直认为在 C(或 C++)函数中这样做是可以的:

somestruct s = {123,};

The first member would be initialized to 123 and the last two would be initialized to 0. I often do the same thing with automatic arrays, writing int arr[100] = {0,};so that all integers in an array are initialized to zero.

第一个成员将被初始化为 123,最后两个成员将被初始化为 0。我经常对自动数组做同样的事情,写入数组int arr[100] = {0,};中的所有整数都被初始化为零。


Recently I read in the GNU C Reference Manualthat:


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

If you do not initialize a structure variable, the effect depends on whether it is has static storage (see Storage Class Specifiers) or not. If it is, members with integral types are initialized with 0 and pointer members are initialized to NULL; otherwise, the value of the structure's members is indeterminate.

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


Can someone please tell me what the C and C++ standards say regarding partial automatic structure and automatic array initialization? I do the above code in Visual Studio without a problem but I want to be compatible with gcc/g++, and maybe other compilers as well. Thanks


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

回答by Alok Save

The linked gcc documentation does not talk of Partial Initializationit just talks of (Complete)Initializationor No Initialization.

链接的 gcc 文档没有谈论Partial Initialization它只是谈论(Complete)InitializationNo Initialization

What is partial Initialization?

什么是部分初始化?

The standards do not define Partial initialization of objects, either there is Complete initialization or No-initialization. Partial Initialization is a non-standard terminology which commonly refers a situation where you provide some initializers but not all i.e: Fewer initializers than the size of the array or the number of structure elements being initialized.

标准没有定义对象的部分初始化,有完全初始化或无初始化。部分初始化是一个非标准术语,通常指的是您提供一些初始化器但不是全部的情况,即:初始化器少于数组的大小或被初始化的结构元素的数量。

Example:

例子:

int array[10] = {1,2};                    //Case 1:Partial Initialization

What is (Complete)Initialization or No Initialization?

什么是(完全)初始化或无初始化?

Initialization means providing some initial value to the variable being created at the same time when it is being created. ie: in the same code statement.

初始化意味着在创建变量的同时为其提供一些初始值。即:在相同的代码语句中。

Example:

例子:

int array[10] = {0,1,2,3,4,5,6,7,8,9};    //Case 2:Complete Initialization
int array[10];                            //Case 3:No Initialization

The quoted paragraph describes the behavior for Case 3.

引用的段落描述了 的行为Case 3

The rules regarding Partial Initialization(Case 1) are well defined by the standard and these rules do not depend on the storage type of the variable being initialized.
AFAIK, All mainstream compilers have 100% compliance to these rules.

Partial Initialization( Case 1)的规则由标准很好地定义,这些规则不依赖于被初始化的变量的存储类型。
AFAIK,所有主流编译器都 100% 遵守这些规则。



Can someone please tell me what the C and C++ standards say regarding partial automatic structure and automatic array initialization?

有人能告诉我 C 和 C++ 标准对部分自动结构和自动数组初始化的看法吗?

The C and C++ standards guarantee that even if an integer array is located on automatic storage and if there are fewer initializers in a brace-enclosed list then the uninitialized elements mustbe initialized to 0.

C 和 C++ 标准保证,即使整数数组位于自动存储中并且如果括号括起来的列表中的初始化器较少,则未初始化的元素也必须初始化为0

C99 Standard 6.7.8.21

C99 标准 6.7.8.21

If there are fewer initializers in a brace-enclosed list than there are elements or members of an aggregate, or fewer characters in a string literal used to initialize an array of known size than there are elements in the array, the remainder of the aggregate shall be initialized implicitly the same as objects that have static storage duration.

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



In C++ the rules are stated with a little difference.

在 C++ 中,规则的表述略有不同。

C++03 Standard 8.5.1 Aggregates
Para 7:

C++03 标准 8.5.1 聚合
第 7 段:

If there are fewer initializers in the list than there are members in the aggregate, then each member not explicitly initialized shall be value-initialized(8.5). [Example:

 struct S { int a; char* b; int c; };
 S ss = { 1, "asdf" };

initializes ss.awith 1, ss.bwith "asdf", and ss.cwith the value of an expression of the form int(), that is,0. ]

如果列表中的初始值设定项少于聚合中的成员数,则每个未显式初始化的成员都应进行值初始化(8.5)。[例子:

 struct S { int a; char* b; int c; };
 S ss = { 1, "asdf" };

ss.a1ss.b"asdf"ss.c形式的表达式的值初始化int(),即0。]

While Value Initialization is defined in,
C++03 8.5 Initializers
Para 5:

虽然值初始化在
C++03 8.5 Initializers
Para 5 中定义:

To value-initializean object of type T means:
— if T is a class type (clause 9) with a user-declared constructor (12.1), then the default constructor for T is called (and the initialization is ill-formed if T has no accessible default constructor);
— if T is a non-union class type without a user-declared constructor, then every non-static data member and base-class component of T is value-initialized;
— if T is an array type, then each element is value-initialized;
— otherwise, the object is zero-initialized

值初始化的类型T的装置的对象:
-如果T是一个类型(第9节)与用户声明的构造(12.1),然后对T中的默认构造函数被调用(以及初始化是形成不良的如果T没有可访问的默认构造函数);
— 如果 T 是没有用户声明的构造函数的非联合类类型,则 T 的每个非静态数据成员和基类组件都进行了值初始化;
— 如果 T 是数组类型,则每个元素都进行了值初始化;
— 否则,对象是零初始化的

回答by caf

In C, objects are neverpartially initialised - if any part of them is initialised, the entire object (and all sub-objects recursively) are initialised. If no explicit initialiser is provided then elements are initialised to "zero of the appropriate type".

在 C 中,对象永远不会被部分初始化——如果它们的任何部分被初始化,则整个对象(以及递归的所有子对象)都会被初始化。如果未提供显式初始化程序,则元素将初始化为“适当类型的零”。

The quote in your question is referring to when the initialiser for the entire object is completely left out, not when a sub-object lacks an initialiser. For example, assuming that arrhas automatic storage duration, then this:

您问题中的引用是指整个对象的初始化程序何时完全被排除在外,而不是子对象缺少初始化程序时。例如,假设arr有自动存储期,那么这个:

int arr[100] = { 123 };

initialises arr[0]to 123and every other element of arrto 0. Whereas this:

初始化arr[0]123与所有其他元素arr0。而这:

int arr[100];

leaves every element of arruninitialised. It is this latter case that the quote is in reference to.

留下arr未初始化的每个元素。引用所指的正是后一种情况。

回答by rocket441

newest gcc versions also allow to "partially" initialize and zeromem at the same time:

最新的 gcc 版本还允许同时“部分”初始化和 zeromem:

typedef struct{
  int a,b,c;
}T;

T s = {0, .b=5};

the struct members now will have these values: a=0, b=5, c=0

结构成员现在将具有以下值: a=0, b=5, c=0

i don't have any info on whether other compilers allow this or not :p

我没有关于其他编译器是否允许这样做的任何信息:p