null null - 27 days ago 13
C Question

What's the difference between an empty initialiser and no initialiser for a struct?

I came across some code similar to this:

struct Struct
{
int a;
int b;
};

int main()
{
struct Struct variable = { }; // ???
variable.a = 4;
variable.b = 6;
}


This is strange. The initialisation of
a
and
b
could be happening in the initialiser (between the curly braces). But they aren't. What's the point in keeping the
= { }
part? The following should be just fine, right?

struct Struct variable;


Or is it? Is having an empty initialiser in any way different to having no initialiser?

My small C handbook states that


For variables without an initialiser: All variables with static scope are implicitly initialised with zero (that is all bytes = 0). All other variables have undefined values!


The caveat is that this is not explicitly mentioning
struct
s.
When is the condition of being without an initialiser met for the fields of a
struct
?
I made the following test:

#include <stdio.h>

struct Struct
{
int a;
int b;
};

int main()
{
struct Struct foo = { };
foo.a = 4;

struct Struct bar;
bar.a = 4;

printf("with list:\t %i\n", foo.b);
printf("without list:\t %i\n", bar.b);
}


With the result being:

with list: 0
without list: 32765


This is confusing. The
struct
without an initialiser list did not get initialised with 0, contrary to what my little C book says.

How do these initialiser lists work with structs exactly?

Answer

The main difference is that an empty initializer:

struct Struct variable = { };

is a syntax error in standard C. (Your compiler might support it as an extension.)

With a valid initializer, such as:

struct Struct variable = { 0 };

(... = { 0 } is valid for any type), any members that aren't given explicit values are implicitly initialized to zero.

With no initializer, an object with static storage duration (defined outside any function or with the static keyword) is initialized to zero. An object with automatic storage duration (inside a function and without the static keyword) is not initialized at all, and its contents will be garbage.

And in fact that's just what your C book says:

For variables without an initialiser: All variables with static scope are implicitly initialised with zero (that is all bytes = 0). All other variables have undefined values!

(It should say storage duration rather than scope, and the initialization isn't necessarily bytewise, but apart from that it's essentially correct.)

Note that "zero" is not necessarily all-bits-0, though that's a common way to implement it. What the language requires is that each member (for structures), or the first member (for unions), or each element (for arrays) is initialized to zero, with the rule applied recursively until you get down to pointers (initialized to NULL), integers (initialized to 0), or floating-point objects (initialized to 0.0). Null pointers and floating-point 0.0 typically are represented as all-bits-0, but the language doesn't require them to be.