(This answer focuses on the differences in initialization, in the case of a struct
only containing integral types)
Both forms set a
and b
to 0
. This is because the Standard defines that all-bits-zero for an integral type must represent a value of 0
.
If there is structure padding, then the calloc
version sets that but the zero-initialization may not. For example:
struct foo a = { 0 }, b = { 0 };
struct foo c, d; memset(&c, 0, sizeof c); memset(&d, 0, sizeof d);
if ( memcmp(&a, &b, sizeof a) )
printf("This line may appear.\n");
if ( memcmp(&c, &d, sizeof c) )
printf("This line must not appear.\n");
A technique you will sometimes see (especially in code designed to fit on systems with small amounts of storage) is that of using memcmp
to compare two structs for equality. When there is padding between structure members, this is unreliable as the padding may be different even though the structure members are the same.
The programmer didn't want to compare structure members individually as that is too much code size, so instead, he will copy structs around using memcpy
, initialize them using memset
; in order to preserve the ability to use memcmp
to check for equality.
In modern programming I'd strongly advise to not do this; and to always use the { 0 }
form of initailization. Another benefit of the latter is that there is no chance of making a mistake with the size argument and accidentally setting too much memory or too little memory.