Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Partially initializing a C struct

This link states that "When an automatic array or structure has a partial initializer, the remainder is initialized to 0". I decided to try out what I read and wrote the following piece of code:

#include <stdio.h> #include <string.h> #include <stdlib.h>  int main(void) {     //int arr[3] = {2};  // line no. 7      struct s {         int si;         int sj;     };      struct s myStruct;     myStruct.si = 9;     printf("%d\n", myStruct.sj); } 

I don't understand why 4096 (which I believe is some "garbage" value) is printed when I comment out line no. 7 and I get 0 when I uncomment line no. 7. I don't think the arr declaration has got something to do with main()'s activation record (or rather myStruct) which should look like (provided we have line no. 7 uncommented):

--------------- |  Saved PC   | --------------- |  arr[2]     | --------------- |  arr[1]     | --------------- |  arr[0]     | --------------- |  si         | --------------- |  sj         | --------------- 

Can somebody please explain what I am missing here?

like image 580
babon Avatar asked May 31 '16 14:05

babon


People also ask

Is it possible to partially initialize structure variable?

Hence in case of partially initialized structure, uninitialized member variable of numerical type (char, int, long, float, double) will be initialized to 0, and pointers will be initialized to NULL. Lets take one more case where in class is to be initialized with 8 and name and age is unknown.

What happens when you partially initialize an array with values?

If an array is partially initialized, elements that are not initialized receive the value 0 of the appropriate type. The same applies to elements of arrays with static storage duration. (All file-scope variables and function-scope variables declared with the static keyword have static storage duration.)

How do you partially initialize an array?

An array may be partially initialized, by providing fewer data items than the size of the array. The remaining array elements will be automatically initialized to zero. If an array is to be completely initialized, the dimension of the array is not required.

Can you initialize in struct?

You can also create and initialize a struct with a struct literal. An element list that contains keys does not need to have an element for each struct field. Omitted fields get the zero value for that field.


2 Answers

When you do this:

struct s myStruct; myStruct.si = 9; 

You are not initializing myStruct. You declare it without an initializer, then run a statement to set one field.

Because the variable is uninitialized, its contents are undefined, and reading it is undefined behavior. This means that seemingly unrelated changes can modify this behavior. In your example adding an extra variable happened to cause myStruct.sj to be 0, but there's no guarantee that this will be the case.

To initialize a variable, you have to give it a value at the time it is defined:

struct s myStuct = { 9 }; 

One you do this, then you'll see the contents of myStruct.sj set to 0. This is guaranteed as per section 6.7.8 of the C standard (with highlighting specific to this case):

10 If an object that has automatic storage duration is not initialized explicitly, its value is indeterminate. If an object that has static storage duration is not initialized explicitly, then:

—if it has pointer type, it is initialized to a null pointer;

if it has arithmetic type, it is initialized to (positive or unsigned) zero;

if it is an aggregate, every member is initialized (recursively) according to these rules;

—if it is a union, the first named member is initialized (recursively) according to these rules.

...

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.

like image 99
dbush Avatar answered Sep 26 '22 22:09

dbush


In your case,

 myStruct.si = 9; 

is an assignment statement, not initialization. In this case, the structure variable (and the corresponding variables) are uninitialized. Thus, you're ending up reading the value of an uninitialized variable sj, which leads to undefined behavior.

You can try

struct s myStruct = {9}; 

to see the implicit initialization in action.

like image 25
Sourav Ghosh Avatar answered Sep 24 '22 22:09

Sourav Ghosh