If a C compiler pads a structure in order to align the fields to their native alignment, and that structure is then initialized, is the padding initialized to zero?
For example the following structure:
typedef struct foo_t_ {
int a;
char b;
int c;
char d;
} foo_t;
On many systems this (poorly designed) structure would have a sizeof(foo_t)
of 16, with a total of 6 bytes of padding, 3 bytes after each of the chars.
If we initialize the structure like:
foo_t foo = { .a = 1, .b = '2' };
then the fields foo.a
will be set to 1 and foo.b
will be set to the character '2'. The unspecified fields (`foo.c' and 'foo.d') will automatically be set to 0. The question is, what happens to the 6 bytes of padding? Will that also automatically be set to 0? or is it undefined behavior?
The use case is that I will be calculating hashes of data structures:
foo_t foo = { .a = 1, .b = '2' };
foo_t bar = { .a = 1, .b = '2' };
uint32_t hash_foo = calc_hash(&foo, sizeof(foo));
uint32_t hash_bar = calc_hash(&bar, sizeof(bar));
and I want to be sure that hash_foo
and hash_bar
are the same. I could guarantee this by first using memset()
to clear the structures, then initializing them, but it seems cleaner to use C initialization instead.
In practice, GCC on my system does clear the padding as well, but I don't know if that is guaranteed.
In general, As per
C11
, for any uninitialized object chapter §6.2.6.1/6,But, if the partial initialization is done, in that case, for rest of the members, the intialization happens as if an object that has static or thread storage duration, then, quoting the same standard, chapter §6.7.9/21
and regarding the implicit initialization of objects with static storage duration, paragraph 10
So, in your case, padding for the remaining objects are guaranteed to be 0, but not for the members which has received the initializers.
So, all over, you should not depend on an implicit initialization of 0, use
memset()
.That being said, in anyway it's not recommended (required) to depend on padding bytes, if any. Use the exact member variables and calculate the hash based on those values.