Le code suivant compile sur un compilateur C ++. 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? P> P>
6 Réponses :
Eh bien, CSTDIO doit être appelé stdio.h. En ce qui concerne la structure, le mot-clé Struct n'est pas requis en C ++. P>
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. P>
Je viens de le tester avec de légères modifications et le compilateur GCC compile avec gcc p> i compile mais donne un avertissement. Puisque mon c est trop rouillé ne peut plus en dire. P> p>
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;
Les structures mutuellement récursives sont possibles dans C. Ils sont faits tout comme vous le dites, avec une déclaration à terme.
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);
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 code>. Le code d'origine n'était pas valide C, votre modifié sur est.
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 Strong> a ajouté: strong> langage C Interdit à déclarer des types de struct dans d'autres structures sans déclarer un membre de ce type. Donc, vous 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. p> p> principal code>?) > xx code> et xx :: yy code>, tandis qu'en C, ils seraient juste xx code> et yy code>. 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. P> STRUCTY YY CODE> 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 code> struct code> avec certaines déclarations de membres de données. Dans votre cas, cela pourrait être un pointeur q code>: p>
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 code> doivent être entièrement des déclarateurs i>. Une déclaration struct code> sans déclaration de membre n'est pas un Déclarateur I>. 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 CODE> Fonctionne de la même manière un non imbriqué code> Déclaration code> dans Main < / code> serait. C'est à dire. Même si struct yy code> est déclaré inside struct xx code>, vous pouvez toujours déclarer struct yy obj; code> dans principal code>.
structure yy code> et membre q code>. La compilation suivante avec gcc code> avec des avertissements maximum sur:
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.