Une autre utilisation du tableau de longueur zéro est une étiquette nommée à l'intérieur d'une structure pour faciliter la vérification du décalage de la structure au moment de la compilation.
Supposons que vous ayez de grandes définitions de structures (s'étendant sur plusieurs lignes de cache) et que vous vouliez 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ù elles traversent 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 en utilisant des extensions GCC comme :
__attribute__((aligned(CACHE_LINE_BYTES)))
Mais il faut quand même s'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 un code comme celui 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 de procéder de cette manière, vous pouvez déclarer un tableau de longueur nulle dans la structure qui agit comme une étiquette nommée avec un nom cohérent mais qui ne consomme pas d'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
....
};
Le code d'assertion d'exécution serait alors 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);
0 votes
Je ne suis pas sûr qu'il doive y avoir soit une tableaux de longueur nulle o struct-hack tag ...
0 votes
@hippietrail, parce que souvent, lorsque quelqu'un demande ce qu'est ce struct, il ne sait pas qu'il est désigné par le terme "flexible array member". S'ils le savaient, ils auraient pu facilement trouver leur réponse. Mais comme il ne le sait pas, il ne peut pas marquer la question comme telle. C'est pourquoi nous ne disposons pas d'une telle balise.
0 votes
Cela pourrait être une raison pour ne pas avoir de balises pour tous les concepts dont certaines personnes ne connaissent pas la terminologie ...
12 votes
Vote pour la réouverture. Je suis d'accord pour dire qu'il ne s'agit pas d'un doublon, parce qu'aucun des autres messages ne traite de la combinaison d'un "struct hack" non standard avec une longueur nulle et de la fonctionnalité C99 bien définie de membre de tableau flexible. Je pense également qu'il est toujours utile pour la communauté des programmeurs C de faire la lumière sur tout code obscur du noyau Linux. Principalement parce que beaucoup de gens ont l'impression que le noyau Linux est une sorte d'état de l'art du code C, pour des raisons inconnues. Alors qu'en réalité, il s'agit d'un terrible fouillis inondé d'exploits non standard qui ne devrait jamais être considéré comme un canon du C.
5 votes
Ce n'est pas un doublon - ce n'est pas la première fois que je vois quelqu'un fermer une question inutilement. Je pense également que cette question enrichit la base de connaissances de l'OS.
0 votes
Également expliqué à la question 2.6 du FAQ comp.lang.c .
1 votes
Duplicata possible de Que se passe-t-il si je définis un tableau de taille 0 en C/C++ ?
0 votes
@Aniket si une question redirige proprement vers une autre, il n'y a pas de perte de "connaissance"... cela réduit seulement la répétition pour le coût d'un clic supplémentaire.