78 votes

Comment cette structure peut-elle avoir sizeof == 0?

Il y a un vieux post en demandant une construction pour qui sizeof reviendrait 0. Il y a quelques score élevé de réponses de la haute réputation des utilisateurs, en disant que dans la norme, aucun type ou variable peut avoir sizeof 0. Et je suis d'accord à 100% avec ça.

Cependant il y a cette nouvelle réponse , qui présente cette solution:

struct ZeroMemory {
    int *a[0];
};

J'étais sur le point de voter et de commenter, mais le temps passé ici m'a appris à vérifier, même les choses que je suis sûr à 100% sur. Donc... à ma grande surprise, les deux gcc et clang afficher les mêmes résultats: sizeof(ZeroMemory) == 0. Même plus, sizeof une variable est - 0:

ZeroMemory z{};
static_assert(sizeof(z) == 0); // Awkward...

Whaaaat...?

Godbolt lien

Comment est-ce possible?

50voto

supercat Points 25534

Avant C était normalisé, de nombreux compilateurs n'aurait eu aucune difficulté de manipulation zéro types de taille tant que le code n'a jamais tenté de soustraire un pointeur vers un zéro de type taille de l'autre. Ces types ont été utiles, et le soutien qui leur a été plus facile et moins cher que le leur interdisant. D'autres compilateurs décidé d'interdire ces types, cependant, et certaines statique affirmation de code peut avoir invoqué le fait qu'ils affichez si le code a essayé de créer une zéro-tableau de taille. Les auteurs de la Norme ont été confrontés à un choix:

  1. Permettre compilateurs en silence accepter zéro de la taille de la matrice de déclarations, même dans les cas où le but de ces déclarations seraient à déclencher une de diagnostic et d'abandon à la compilation et à exiger que tous les compilateurs acceptent de telles déclarations (mais pas nécessairement silencieusement) que la production de zéro des objets de la taille.

  2. Permettre compilateurs en silence accepter zéro de la taille de la matrice de déclarations, même dans les cas où le but de ces déclarations seraient à déclencher une de diagnostic et d'abandon de la compilation, et de permettre compilateurs face à de telles déclarations, soit interrompre la compilation ou de continuer à leur guise.

  3. Exiger que les implémentations de délivrer un diagnostic si le code déclare un zéro-tableau de taille, mais alors permettre des implémentations soit abandonner la compilation ou de continuer (avec tout ce que la sémantique ils l'entendent) à leurs loisirs.

Les auteurs de la Norme opté pour la #3. Par conséquent, zéro-tableau de taille déclarations sont considérées par la Norme "extension", même si ces constructions ont été largement pris en charge avant de la Norme interdit.

La Norme C++ permet l'existence d'objets vides, mais dans un effort pour permettre à l'adresse des objets vides pour être utilisable sous forme de jetons de son mandat qu'ils ont une taille minimum de 1. Pour un objet qui n'a pas de membres pour avoir une taille de 0 serait donc de violer la Norme. Si un objet contient zéro de la taille des membres, cependant, la Norme C++ impose pas d'exigences sur la façon dont il est traité au-delà du fait qu'un programme contenant une telle déclaration doit déclencher un diagnostic. Depuis plus de code qui utilise de telles déclarations attend les objets qui en résultent ont une taille de zéro, le plus utile de comportement pour les compilateurs de la réception de ce code est de les traiter ainsi.

41voto

bolov Points 4005

Comme l'a souligné Jarod42 zéro matrices de taille ne sont pas la norme C++, mais GCC et Clang extensions.

L'ajout d' -pedantic produit cet avertissement:

5 : <source>:5:12: warning: zero size arrays are an extension [-Wzero-length-array]
    int *a[0];
           ^

J'oublie toujours qu' std=c++XX (au lieu de std=gnu++XX) n'a pas de désactiver toutes les extensions.

Cela n'explique toujours pas l' sizeof comportement. Mais au moins nous savons que ce n'est pas la norme...

18voto

Rxmsc Points 927

En C++, un zéro-tableau de taille est illégal.

ISO/IEC 14882:2003 8.3.4/1:

[..] Si la constante de l'expression (5.19) est présent, il doit être une expression constante et sa valeur doit être supérieure à zéro. L'expression constante spécifie la limite de (nombre d'éléments) de la matrice. Si la valeur de la constante d'expression est - N, le tableau a N éléments numérotés 0 de N-1, et le type de l'identifiant de l' D est "dérivée de demande de déclaration de type de liste de tableau de N T". [..]

g++ requiert l' -pedantic drapeau de donner un avertissement à un zéro-tableau de taille.

4voto

haccks Points 33022

Les tableaux de longueur nulle sont une extension de GCC et Clang. L'application de sizeof aux tableaux de longueur nulle est évaluée à zéro .

Une classe C ++ (vide) ne peut pas avoir la taille 0 , mais notez que la classe ZeroMemory n'est pas vide. Il a un membre nommé avec une taille 0 et une application de sizeof retournera zéro.

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