1

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

null
  • 5,207
  • 1
  • 19
  • 35
  • Fields of a struct cannot have a different storage class than the struct. Think of the entire struct as an opaque binary blob with a certain size for the purpose of storage class. In no case will C compilers be assured of zeroing out them memory in that blob for you without explicitly declaring them static. Also your variables in the code example have auto scope, not static. – BadZen Nov 09 '16 at 23:42
  • Take a look at http://stackoverflow.com/questions/11152160/initializing-a-struct-to-0 – Paul92 Nov 09 '16 at 23:43
  • 4
    Empty initializers are technically not allowed in the C standard. Try compiling with `-std=c99 -pedantic` to see that. – kaylum Nov 09 '16 at 23:44
  • 1
    `= {}` initializer is something you could see in C++ code. It is illegal in C code. – AnT stands with Russia Nov 09 '16 at 23:49
  • @AnT this explains why I found so much stuff about C++ when searching for an answer. – null Nov 09 '16 at 23:55
  • @BadZen: I don't see how this is realted to the storage class. The whole `struct` is automatic and the fields don't have a disfferent storage class. – too honest for this site Nov 10 '16 at 00:06
  • `struct`s are _types` (precisely: _type-specifiers_), not variables. That text applies to "variables" (which is a bit sloppy, it should actually refer to _objects_ in general. However, it is exactly like your book says. Don't confuse the `static` storage class specifier with _static_ storage duration! Note there is nothing like "static scope", that is nonsense. Maybe you get a better book or start reading the [standard](http://port70.net/~nsz/c/c11/n1570.html#6.2.4p1) which is the only authoritative reference. – too honest for this site Nov 10 '16 at 00:10
  • @Olaf the "static scope" was just my bad translation, sorry. You are spot on that identifying the situation and how the text applies to it was the problem. – null Nov 10 '16 at 00:19

1 Answers1

5

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.

Keith Thompson
  • 254,901
  • 44
  • 429
  • 631
  • My mistake was to skip "static" in the text and thus making false assumptions how it would apply to the code at hand. The book actually says storage duration, I just translated it wrong, my bad. – null Nov 10 '16 at 00:04
  • 1
    @Olaf: `0` and zero are synonymous as far as I'm concerned. "Zero" does not mean "all-bits-zero"; it's just the English word for `0`. – Keith Thompson Nov 10 '16 at 00:16
  • @Olaf: How about "Note that "zero" is not necessarily all-bits-0", which I wrote in my answer. – Keith Thompson Nov 10 '16 at 00:30