50 votes

Taille de retour possible 0 (zéro)

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?

40voto

Michael Burr Points 181287

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.

20voto

AndreyT Points 139512

sizeof ne retourne jamais 0 en C et en C ++. Chaque fois que vous voyez sizeof évaluer pour 0 c'est un bug / glitch / extension d'un compilateur spécifique qui n'a rien à voir avec le langage.

9voto

bta Points 22525

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' sizeofopé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.

5voto

Michael Mrozek Points 44120

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

2voto

alvin Points 784

à 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).

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X