Est-il possible pour l'opérateur sizeof de renvoyer 0 (zéro) en C ou C ++? Si c'est possible, est-ce correct du point de vue des normes?
Réponses
Trop de publicités?En C++ une classe vide ou struct a un sizeof
au moins 1 par définition. À partir de la norme C++, 9/3 "Classes": "l'intégralité des objets et membre de la sous-objets de type classe est non nulle de taille."
En C un vide struct n'est pas permise, sauf par extension (ou une faille dans le compilateur).
C'est une conséquence de la grammaire (ce qui nécessite qu'il y ait quelque chose entre les accolades) avec cette phrase de 6.7.2.1/7 "de la Structure et de l'union des prescripteurs": "Si la struct-déclaration-liste contient pas de membres nommés, le comportement est indéfini".
Si un zéro de la taille de la structure est autorisé, alors c'est une extension du langage (ou une faille dans le compilateur). Par exemple, dans GCC, l'extension est documenté dans les Structures"avec Pas de Membres", qui dit:
GCC permet à une structure C ne pas avoir de membres:
struct empty { };
La structure de taille zéro. En C++, des structures vides font partie de la langue. G++ traite des structures vides, comme s'ils avaient un seul membre de type
char
.
Chaque objet en C doit avoir une adresse unique. Formulé d'une autre manière, une adresse doit pas détenir plus d'un objet d'un type donné (dans l'ordre de déréférencement du pointeur de travail). Cela étant dit, envisager un "vide" struct:
struct emptyStruct {};
et, plus précisément, un tableau d'entre eux:
struct emptyStruct array[10];
struct emptyStruct* ptr = &array[0];
Si les objets étaient en effet vide (qui est, si l' sizeof(struct emptyStruct) == 0
), alors ptr++ ==> (void*)ptr + sizeof(struct emptyStruct) ==> ptr
, ce qui n'a pas de sens. Dont l'objet serait - *ptr
puis reportez-vous à, ptr[0]
ou ptr[1]
?
Même si la structure n'a pas de contenu, le compilateur doit le traiter comme si c'est un octet de longueur afin de maintenir la "une seule adresse, un seul objet" principe.
Le langage C spécification (section A7.4.8) les mots de cette exigence
lorsqu'il est appliqué à une structure ou d'une union, le résultat (de l'
sizeof
opérateur) est le nombre d'octets de l'objet, y compris tout rembourrage nécessaire pour faire l'objet de la tuile d'un tableau
Depuis un rembourrage octet doit être ajoutée à un objet "vide" pour travailler dans un tableau, sizeof()
doit donc retourner une valeur au moins égale à 1 pour toutes les entrées valides.
Edit:
Article A8.3 de la C spec appelle une struct sans une liste de membres d'un type incomplète, et la définition de l' sizeof
spécifiquement etats (italiques ajoutés):
L'opérateur (sizeof) ne peut pas être appliqué à un opérande de la fonction type ou de type incomplète, ou d'un peu de champ.
Cela impliquerait que l'utilisation d' sizeof
sur un vide struct serait tout aussi valide que sur un type de données qui n'a pas été défini. Si votre compilateur permet l'utilisation de vider les structures, être conscient que l'utilisation de sizeof
sur eux n'est pas permis que par le C spec. Si votre compilateur permet de le faire de toute façon, comprendre que c'est non-standard de comportement qui ne fonctionnera pas sur tous les compilateurs, ne pas compter sur ce comportement.
Edit: Voir aussi cette entrée dans Bjarne Stroustrup la FAQ.
Vide les structures, comme isbadawi mentionne. Aussi gcc permet de tableaux de 0 taille:
int a[0];
sizeof(a);
EDIT: Après avoir vu le lien MSDN, j'ai essayé le vide struct dans VS2005 et sizeof ne retourne 1. Je ne suis pas sûr si c'est un VS bug ou si la spécification est d'une certaine manière flexible à propos de ce genre de chose
à mon avis, c'est mieux que sizeof renvoie la valeur 0 pour une structure de taille 0 (dans l'esprit de c). mais ensuite, le programmeur doit être prudent quand il prend la sizeof un vide struct.
mais il peut causer un problème. lorsque le tableau de ces structures est défini,
&arr[1] == &arr[2] == &arr[0]
qui leur fait perdre leur identité.
je suppose que cela ne marche pas répondre directement à votre question, s'il est possible ou non. eh bien peut-être possible selon le compilateur. (comme il est dit dans Michael la réponse ci-dessus).