Une autre utilisation du tableau de longueur nulle est une étiquette nommée à l'intérieur d'une structure pour aider à la vérification du décalage de la structure au moment de la compilation.
Supposons que vous ayez des définitions de structure volumineuses (couvrant plusieurs lignes de cache) que vous souhaitez vous assurer qu'elles sont alignées sur la limite de la ligne de cache à la fois au début et au milieu, là où elle traverse la limite.
struct example_large_s
{
u32 first; // align to CL
u32 data;
....
u64 *second; // align to second CL after the first one
....
};
Dans le code, vous pouvez les déclarer à l'aide d'extensions GCC comme:
__attribute__((aligned(CACHE_LINE_BYTES)))
Mais vous voulez toujours vous assurer que cela est appliqué au moment de l'exécution.
ASSERT (offsetof (example_large_s, first) == 0);
ASSERT (offsetof (example_large_s, second) == CACHE_LINE_BYTES);
Cela fonctionnerait pour une seule structure, mais il serait difficile de couvrir plusieurs structures, chacune ayant un nom de membre différent à aligner. Vous obtiendrez probablement du code comme ci-dessous où vous devez trouver les noms du premier membre de chaque structure:
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);
Au lieu d'aller de cette façon, vous pouvez déclarer un tableau de longueur nulle dans la structure agissant comme une étiquette nommée avec un nom cohérent mais ne consomme aucun espace.
#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
....
};
Ensuite, le code d'assertion d'exécution serait beaucoup plus facile à maintenir:
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);