Le code suivant imprime la même adresse pour les deux Ma question est que C standard autorise plusieurs variables d'avoir une même adresse ou qu'il s'agit simplement d'une extension de GCC? P> P> A code> et
B code> à l'aide de GCC (non testé avec d'autres compilateurs):
4 Réponses :
dans la norme C, la matrice de taille zéro n'est pas autorisée. P>
Si vous le compilez avec une option zéro.c: 3: 6: AVERTISSEMENT: ISO C interdit la graisse de taille zéro 'A' [-> Pedantic] P>
blockQuote> -pedantic code> à l'aide de GCC. Cela donnera un avertissement, en disant: p>
Le paragraphe C11 6.7.6.2P1 dit :
contraintes strong> p>
- En plus des qualificateurs de type optionnels et du mot-clé statique, le
[ code> et
] code> peut délimiter une expression ou *. S'ils délimitent une expression (qui spécifie la taille d'un tableau), l'expression doit avoir un type d'entier. Si l'expression est une expression constante,
il doit avoir une valeur supérieure à zéro fort>. Li> ol> blockQuote> Comme votre programme viole un
doit strud> (0 n'est pas supérieur à zéro), le programme aurait un comportement indéfini em>, sauf que dans ce cas, il apparaît dans les contraintes strong> section. Comme la section 4 Conformité dit P> 4 Conformité h1>
dans cette norme internationale, "" doit "être
interprété comme une exigence sur une mise en œuvre forte> ou sur un programme; Inversement, "ne" doit pas "doit être interprété comme une interdiction. P> li> Si un "" doit "ou" "ne" doit pas "exigence", qui apparaît en dehors d'une contrainte ou d'une contrainte d'exécution est violée, le comportement n'est pas défini. Le comportement non défini est autrement indiqué dans la présente Norme internationale par les mots «comportement non défini» ou par l'omission de toute définition explicite du comportement. Il n'y a pas de différence d'emphase parmi ces trois; Ils décrivent tous «comportement indéfini». p> li> ol> blockQuote>
aussi, le 5.1.1.3p1 < / a> dit: p>
- Une implémentation conforme
doit produire au moins un message de diagnostic strong> (identifié de manière définie par la mise en oeuvre) si une unité de traduction de prétraitement ou une unité de traduction «forte> contient une violation de la syntaxe forte> toute syntaxe règle ou contrainte forte>, même si le comportement est également explicitement spécifié comme non défini ou défini par la mise en œuvre. Les messages de diagnostic ne doivent pas nécessairement être produits dans d'autres circonstances. [9]) li> ol> blockQuote> avec notes de bas de page Dit: P>
9) L'intention est que une mise en œuvre devrait identifier la nature de, et dans la mesure du possible, chaque violation. Bien entendu, une implémentation est libre de produire n'importe quel nombre de diagnostics tant que le programme valide est toujours correctement traduit. il peut également traduire avec succès un programme invalide. strong> p> blockQuote>
Ainsi, p>
C11 n'a pas de matrices de taille 0. P> li>
La présence de tels tableaux est une violation de contraintes EM> p> li>
Cependant, GCC permet Les matrices de taille zéro comme extension a> p> li>
une implémentation C conforme
doit forte> produire un message de diagnostic sur une telle utilisation. P> li> que GCC compile celui-ci avec des paramètres par défaut sans émettre un message de diagnostic même lorsque
-std = c11 code> est défini fait fonctionner
gcc -std = c11 code> non Mise en œuvre conforme. P> li>
the Documentation GCC indique que : P>
[...] Pour obtenir tous les diagnostics requis par la norme, vous devez également spécifier
-peantic code> (ou
-pedantic-erreurs code> si vous voulez qu'ils soient erreurs plutôt que des avertissements). p> blockQuote> li>
Ainsi d'utiliser GCC pour compiler de manière à ce qu'il soit conforme à la norme C11, vous devez utiliser explicitement au moins
gcc -std = c11 -peantique code>; Et puis vous obtiendrez: p>
XXX PRE> LI> Toutefois, GCC compilera toujours votre programme, même s'il s'agit d'un programme incorrect em> (sauf si vous n'utilisez pas
- Erreurs de vitesse code>); Dans ce cas naturellement, aucune des exigences de la norme ne s'appliquera. P> li> ul>
puisque la norme C n'autorise pas vraiment les objets de taille zéro (si je lis correctement, une définition de structure doit également avoir au moins un membre, etc.), et c'est plus que ce que les objets distincts doivent occuper un espace distinct en mémoire où proviennent les adresses distinctes des objets; La norme ne spécifie rien des adresses d'objets de taille 0. p> p>
Comme d'autres ont déjà dit que les tableaux de longueur ne sont pas autorisés dans le compilateur C & GCC standard lui permettent d'extension. J'aimerais ajouter une chose de plus: le comportement de votre programme que vous avez posté en question est non défini . Vous devez lancer vers Voir cette réponse: Printf et pointeurs P> void * code> lors de l'utilisation de% p spécificateur de format, car
printf code> 'S
% p code> Spécificateur de format attend un argument de type
vide * code>. p>
En réalité, cela est discutable, puisque void * code> et
char * code> est compatible.
@Anttihaapala: la norme le dit-elle?
Ça ne le dit pas dans printf code> (doit être pointeur sur
vide * code>); Toutefois
Char * CODE> et
VOID * CODE> sont compatibles conformément au
VA_ARG CODE>.
@Destructeur: C standard dit que vide * code> et
char * code> Les pointeurs partagent des représentations d'objet identiques et des exigences d'alignement, qui est "destinée à impliquer l'interchangeabilité comme des arguments à des fonctions, de retour des valeurs de retour de fonctions et membres des syndicats "
Notez que la réponse liée utilise int * code> qui n'est pas garantie pour être compatible.
La norme C peut dire que char * code> et
void * code> est compatible pour
va_arg code>, mais cela ne dit pas que
printf Le code> doit être mis en œuvre comme si vous utilisez
VA_ARG code> et "signifiait impliquer l'interchangeabilité comme des arguments" est non normatif. Formellement, le comportement est toujours indéfini.
Ce tableau de longueur zéro est une extension GCC et n'est pas pris en charge par la bibliothèque standard, le comportement dépend de la mise en oeuvre de l'extension GCC p>
Vous pouvez voir les documents GCC ici P>
6.17 Des tableaux de longueur zéro p>
Un réseau de longueur zéro code> est appelé tableau
flexible (code> p>
Le code dans la question ne concerne pas les membres de la matrice flexibles.
Étant donné que les tableaux de longueur zéro sont une extension GCC, le comportement d'une matrice de longueur zéro est également une extension GCC. (Indice: essayez
cc -std = c89 -peal -wall -wall x.c code>).
@ Robᵩ est-il documenté partout dans les documents de GCC ou de liker?
La norme C n'autorise pas les matrices de longueur zéro. La norme C n'a rien à dire sur les adresses des tableaux de longueur zéro.
Curieux de savoir comment une matrice de longueur zéro serait représentée dans C.
Ils sont dans des champs disjoints, une variable de types (ou différents) pourrait avoir la même adresse.
@ Robᵩ pourquoi c89? Utilisez la norme la plus récente.