Partially initializing a C struct

ⅰ亾dé卋堺 提交于 2019-12-04 22:18:58

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.

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.

That's not an initializer -- your structure is uninitialized, then you assign only si. sj remains uninitialized.

The book is referring to this kind of code:

struct s myStruct = {9};

... where sj is guaranteed to be 0.

This is basically a - more-or-less- complete example for the great answers others already gave.

#include<stdio.h>

struct{
  int a;
  int b;
}obj1={.a=0}; //Partial initialization

typedef struct struct_B{
  int a;
  int b;
}struct_B;

int main(void)
{
  printf("obj1.b : %d\n",obj1.b);
  struct_B obj2={.b=1,.a=0,0}; // b's first value is overridden here as 0 immediately follows a
  printf("obj2.b : %d\n",obj2.b);
  struct_B obj3={0}; //Partial initialization, here the '0' value is meant for a as it comes first in the declaration
  printf("obj3.b : %d\n",obj3.b);
  struct_B obj4={.a=0}; //Partial initialization
  printf("obj4.b : %d\n",obj4.b);
  return 0;
}

Output:

obj1.b : 0
obj2.b : 0
obj3.b : 0
obj4.b : 0
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!