Quel est le but d’un tableau de longueur zéro dans une structure?

Lorsque je regarde le code du kernel Linux, j’ai trouvé le code ci-dessous:

struct thread_info { struct task_struct *task; struct exec_domain *exec_domain; unsigned long flags; __u32 status; __u32 cpu; int preempt_count; mm_segment_t addr_limit; struct restart_block restart_block; void __user *sysenter_return; unsigned long previous_esp; __u8 supervisor_stack[0]; }; 

Notez que la dernière variable “supervisor_stack”, c’est un tableau de longueur zéro, quelle est son utilisation? Merci d’avance!

C’est la version pré-C99 d’un membre de tableau flexible, offerte par GCC en tant qu’extension.

La méthode C99 consiste à définir le membre de tableau flexible avec des parenthèses vides,

 __u8 supervisor_stack[]; 

Il est utilisé pour stocker des données dont la quantité n’est pas contiguë à la structure. La mémoire est allouée sous la forme

 struct foo *ptr = malloc(sizeof *ptr + whatever_is_needed); 

Au paragraphe 18 de 6.7.2.1, la norme (projet N1570) les décrit:

En tant que cas particulier, le dernier élément d’une structure avec plus d’un membre nommé peut avoir un type de tableau incomplet; cela s’appelle un membre de tableau flexible. Dans la plupart des cas, le membre de tableau flexible est ignoré. En particulier, la taille de la structure est comme si le membre de tableau flexible était omis, sauf qu’il pouvait avoir plus de remplissage que l’omission impliquerait. Cependant, quand a . (ou -> ) L’opérateur a un opérande gauche qui est (un pointeur sur) une structure avec un membre de tableau flexible et l’opérande droite nomme ce membre, il se comporte comme si ce membre était remplacé par le plus long tableau (avec le même type d’élément) ) qui ne rend pas la structure plus grande que l’object auquel on accède; le décalage du tableau doit restr celui du membre du tableau flexible, même si cela diffère de celui du tableau de remplacement. Si ce tableau n’a pas d’éléments, il se comporte comme s’il comportait un élément mais le comportement n’est pas défini si l’on tente d’accéder à cet élément ou de générer un pointeur au-delà.

C’est un hack C commun pour déclarer ce que l’on peut appeler un tableau de longueur variable (où vous définissez la taille au moment de l’allocation)

Exemple:

 struct line { int length; char contents[0]; }; struct line *thisline = (struct line *) malloc (sizeof (struct line) + this_length); thisline->length = this_length; 

De cette façon, vous avez une définition de structure de vos données, qui stocke également la longueur du tableau pour des raisons évidentes, mais vous n’êtes pas limité par la taille fixe généralement associée à une structure.

Exemple pris ici (aussi plus d’infos ici)