Eine andere Verwendung des Arrays mit der Länge Null ist die Verwendung einer benannten Bezeichnung innerhalb einer Struktur, um die Überprüfung des Kompilierungszeit-Strukturversatzes zu unterstützen.
Angenommen, Sie haben einige große Strukturdefinitionen (die mehrere Cache-Zeilen umfassen), die Sie sicherstellen möchten, dass sie sowohl am Anfang als auch in der Mitte, in der sie die Grenze überschreiten, an der Cache-Zeilengrenze ausgerichtet sind.
struct example_large_s
{
u32 first; // align to CL
u32 data;
....
u64 *second; // align to second CL after the first one
....
};
Im Code können Sie sie mit GCC-Erweiterungen wie folgt deklarieren:
__attribute__((aligned(CACHE_LINE_BYTES)))
Sie möchten jedoch weiterhin sicherstellen, dass dies zur Laufzeit erzwungen wird.
ASSERT (offsetof (example_large_s, first) == 0);
ASSERT (offsetof (example_large_s, second) == CACHE_LINE_BYTES);
Dies würde für eine einzelne Struktur funktionieren, aber es wäre schwierig, viele Strukturen abzudecken, von denen jede einen anderen Mitgliedsnamen hat, der ausgerichtet werden muss. Sie würden höchstwahrscheinlich den folgenden Code erhalten, in dem Sie die Namen des ersten Mitglieds jeder Struktur finden müssen:
assert (offsetof (one_struct, <name_of_first_member>) == 0);
assert (offsetof (one_struct, <name_of_second_member>) == CACHE_LINE_BYTES);
assert (offsetof (another_struct, <name_of_first_member>) == 0);
assert (offsetof (another_struct, <name_of_second_member>) == CACHE_LINE_BYTES);
Anstatt diesen Weg zu gehen, können Sie ein Array mit der Länge Null in der Struktur deklarieren, das als benannte Bezeichnung mit einem konsistenten Namen fungiert, aber keinen Speicherplatz belegt.
#define CACHE_LINE_ALIGN_MARK(mark) u8 mark[0] __attribute__((aligned(CACHE_LINE_BYTES)))
struct example_large_s
{
CACHE_LINE_ALIGN_MARK (cacheline0);
u32 first; // align to CL
u32 data;
....
CACHE_LINE_ALIGN_MARK (cacheline1);
u64 *second; // align to second CL after the first one
....
};
Dann wäre der Laufzeit-Assertionscode viel einfacher zu pflegen:
assert (offsetof (one_struct, cacheline0) == 0);
assert (offsetof (one_struct, cacheline1) == CACHE_LINE_BYTES);
assert (offsetof (another_struct, cacheline0) == 0);
assert (offsetof (another_struct, cacheline1) == CACHE_LINE_BYTES);