Wenn ein C-Compiler eine Struktur auffüllt, um die Felder an ihre native Ausrichtung auszurichten, und diese Struktur dann initialisiert wird, wird das Padding auf Null initialisiert?Initialisiert C Strukturauffüllung auf Null?
Zum Beispiel die folgende Struktur:
typedef struct foo_t_ {
int a;
char b;
int c;
char d;
} foo_t;
Auf vielen Systemen dieser (schlecht konzipiert) Struktur eine sizeof(foo_t)
von 16, mit insgesamt 6 Bytes padding, 3 Bytes nach jedem der Zeichen haben würde.
Wenn wir die Struktur wie initialisieren:
foo_t foo = { .a = 1, .b = '2' };
dann die Felder foo.a
-1 und foo.b
gesetzt werden wird, um den Charakter festgelegt werden ‚2‘. Die nicht spezifizierten Felder (`foo.c 'und' foo.d ') werden automatisch auf 0 gesetzt. Die Frage ist, was passiert mit den 6 Bytes des Padding? Wird das auch automatisch auf 0 gesetzt? oder ist es undefiniertes Verhalten?
Der Anwendungsfall ist, dass ich Hashes von Datenstrukturen Berechnung werden:
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));
und ich möchte sicher sein, dass hash_foo
und hash_bar
gleich sind. Ich könnte dies garantieren, indem ich zuerst memset()
benutze, um die Strukturen zu löschen und sie dann zu initialisieren, aber es scheint sauberer zu sein, stattdessen C-Initialisierung zu verwenden.
In der Praxis, GCC auf meinem System löscht auch die Auffüllung, aber ich weiß nicht, ob das garantiert ist.
Wäre die Referenz auf diesen Speicher in keinem Fall UB? –
Warum machen Sie den Hash nicht zu einer Funktion der tatsächlichen Strukturelemente ohne Abhängigkeit von der Auffüllung? –
Beziehen Sie sich in Ihrem Beispiel auf einen Fall, in dem die Variable lokal in einer Funktion oder global deklariert wird? –