C and C++ : Partial initialization of automatic structure

C++C

C++ Problem Overview


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

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.


Recently I read in the GNU C Reference Manual that:

> 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.


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++ Solutions


Solution 1 - C++

The linked gcc documentation does not talk of Partial Initialization it just talks of (Complete)Initialization or No 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.

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.


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

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 must be initialized to 0.

C99 Standard 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++03 Standard 8.5.1 Aggregates
Para 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.a with 1, ss.b with "asdf", and ss.c with the value of an expression of the form int(), that is,0. ]

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

>To value-initialize an 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

Solution 2 - C++

In C, objects are never partially 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".

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 arr has automatic storage duration, then this:

int arr[100] = { 123 };

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

int arr[100];

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

Solution 3 - C++

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

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

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

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionloopView Question on Stackoverflow
Solution 1 - C++Alok SaveView Answer on Stackoverflow
Solution 2 - C++cafView Answer on Stackoverflow
Solution 3 - C++rocket441View Answer on Stackoverflow