11
votes

Structures imbriquées

Le code suivant compile sur un compilateur C ++. XXX

S'il y aurait une différence de comportement lors de la compilation d'un compilateur C?
I.e. Y aurait-il une erreur de compilateur?


1 commentaires

Je n'ai pas de compilateur C. Mais j'ai vu cet exemple dans un texte C en disant que cela entraînera une erreur de compilateur.


6 Réponses :


0
votes

Eh bien, CSTDIO doit être appelé stdio.h. En ce qui concerne la structure, le mot-clé Struct n'est pas requis en C ++.

Vous ne définissez pas vraiment les membres de la structure, mais les membres du pointeur, il semble donc plausible qu'il fonctionne dans les deux cas.


0 commentaires

0
votes

Je viens de le tester avec de légères modifications et le compilateur GCC xxx

compile avec gcc xxx

i compile mais donne un avertissement. Puisque mon c est trop rouillé ne peut plus en dire.


0 commentaires

0
votes

Basé sur ma brève recherche et le message d'erreur posté par Otto, il apparaît que c ne permet pas aux structures d'être des conteneurs d'espace de noms à usage général tels que les classes et les structures de C ++ sont (naturellement, car c ne prend même pas de classes) . Donc, vous ne pouvez pas nidifier les définitions de structure dans C. Vous devrez déclarer la structure interne en dehors de la déclaration de structure extérieure, comme celle-ci:

struct xx;


1 commentaires

Les structures mutuellement récursives sont possibles dans C. Ils sont faits tout comme vous le dites, avec une déclaration à terme.



4
votes

Voici quelques changements (grâce à AndreyT):

Il est évident que vous devez changer les en-têtes pour faire de cette compilation. Mais même alors, cela semble ne pas être standard c comme AndreyT a souligné. Néanmoins, certains compilateurs, comme GCC, le compilent-ils toujours comme prévu et ne délivrent que un avertissement. De même, Microsoft ne semble pas interpréter la norme trop strictement: p>

"Les déclarations de structure peuvent également être spécifiées sans déclarateur lorsqu'ils sont membres d'une autre structure ou union" P> BlockQuote>

Pour le rendre standard C Vous devez transformer votre déclaration "Struct YY" dans une définition. Ensuite, votre code sera valide dans C et en C ++. Pour illustrer ce qui se passe, je l'ai réécrit dans A, à mon avis, de manière plus compréhensible et ajouté un petit test sur ce qui se passe. P> xxx pré>

vous pouvez facilement voir , que vous avez une structure YY avec un pointeur sur XX et que la structure XX a un pointeur à YY. Cela équivaut à celui qui peut être écrit comme suit dans ANSI-C: P>

test.q = (xx::yy*)malloc(sizeof(xx::yy));
test.q->s = 'a';
test.q->p = (xx*)malloc(sizeof(xx));
test.q->p->x = 1; 
test.q->p->q = (xx::yy*)malloc(sizeof(xx::yy));
test.q->p->q->s = 'b';
printf("s: %c\n", test.q->s);
printf("x: %d\n", test.q->p->x);
printf("s: %c\n", test.q->p->q->s);


1 commentaires

Eh bien, votre deuxième exemple "équivalent" fait une modification critique qui le rend valide C. La modification est la déclaration de membre q . Le code d'origine n'était pas valide C, votre modifié sur est.



18
votes

Le code de votre message est évidemment incomplet, juste des déclarations, il est donc difficile de dire quelque chose de concluant.

sur la différence évidente est qu'en C ++, le type de structure interne sera un membre du type de structure externe, tandis que dans C LANGUE Les deux types de struct seront membres de la même portée (englobante). (BTW, a-t-il eu votre intention de les déclarer localement dans principal ?) > xx et xx :: yy , tandis qu'en C, ils seraient juste xx et yy . Cela signifie que le code supplémentaire serait différent pour C et C ++ et s'il compilait en C ++, il ne compilerait pas en C et vice versa.

a ajouté: langage C Interdit à déclarer des types de struct dans d'autres structures sans déclarer un membre de ce type. Donc, vous STRUCTY YY La déclaration est illégale en C et produira un message de diagnostic du compilateur. Si vous vouliez que votre code devienne légal en C et C ++, vous devez combiner la déclaration struct avec certaines déclarations de membres de données. Dans votre cas, cela pourrait être un pointeur q : xxx

ce qui précède est légal en C et C ++ (en tenant compte des différences que j'ai expliquées plus tôt) , mais votre déclaration d'origine n'est pas légale en c.


5 commentaires

Bonne observation à propos de C ++. Mais êtes-vous sûr que la Déclaration de la structure YY est illégale? Il va compiler simplement bien avec GCC, sauf l'avertissement et produit également le comportement attendu.


Oui, je suis sûr. C Grammaire de langage dit explicitement que les "entrailles" d'un struct doivent être entièrement des déclarateurs . Une déclaration struct sans déclaration de membre n'est pas un Déclarateur . GCC l'accepte comme une extension. GCC a beaucoup d'extensions. GCC n'est pas bon pour "essayer" dans le but de vérifier la légalité du code. Comeau Online est beaucoup mieux pour cette fin.


Merci pour la clarification. J'ai changé ma réponse en fonction de vos remarques. Malheureusement, je reçois seulement un uppote.


Est la structure yy accessible de l'extérieur struct xx. Je pensais que ce n'est que Falculé dans la structure XX. Si vous essayez de déclarer un objet de structure YY dans la structure principale, mais à l'extérieur, vous devez redéfinir la structure YY à l'extérieur, n'est-ce pas? J'ai eu l'idée de lire qu'il y a 4 espaces de noms dans C et l'un d'entre eux est membre de la structure. Mais je suppose que je l'ai mélangé avec portée ...


@Rich: Non, si vous parlez de C. La déclaration "Netd" STREST AA Fonctionne de la même manière un non imbriqué Déclaration dans Main < / code> serait. C'est à dire. Même si struct yy est déclaré inside struct xx , vous pouvez toujours déclarer struct yy obj; dans principal .



2
votes

c ne vous permet pas de nier une déclaration de type à l'intérieur d'une définition de la fonction. également, pour éliminer l'avertissement de "ne déclarant rien, vous devriez fusionner les déclarations de type structure yy et membre q . La compilation suivante avec gcc avec des avertissements maximum sur: xxx


0 commentaires