Yes, the lines
static FOO foo_zero;
and
*foo = foo_zero;
arrange that every new instance of struct FOO
allocated by init_foo()
is initialized just as if someone had said
struct FOO new_foo = { 0 };
Specifically, all integer fields will be initialized to 0, all floating-point fields will be initialized to 0.0, and all pointer fields will be initialized to null pointers (aka NULL
, or nullptr
in C++).
This is a nice technique, because it's both simpler and, strictly speaking, more portable than other techniques.
There's a discussion percolating in the comments about the alternative possibilities of doing
foo = malloc(sizeof(*foo));
memset(foo, 0, sizeof(*foo));
or
foo = calloc(1, sizeof(*foo));
Both of these would initialize the brand-new struct FOO
to all-bits-0. The subtle problem here -- which is so subtle that many programmers would not call it a problem at all -- is that it is theoretically possible for a processor and/or operating system to represent a floating-point value of 0.0, or a null pointer, with a bit pattern of something other than all-bits-0.
But if you're on such a processor, then doing
float f = 0;
or
char *p = 0;
will do the right thing, initializing the variable with the proper zero value, even if it's not all-bits-0. And for an aggregate such as struct FOO
, doing
struct FOO new_foo = { 0 };
is equivalent to explicitly initializing each of its members with 0, meaning you get the proper zero value, even if that's not all-bits-0. And, finally, any time you declare a variable with static duration, as in
static FOO foo_zero;
you get an implicit initialization as if you'd said = { 0 };
, and therefore the default (static) initialization, too, gives you those correct zero values no matter what.
If you're still curious about calloc
's all-bits-0 guarantee, you can read a bit more about it in question 7.31 of the C FAQ list.