Typedef struct en C Vs C ++
Cela donne une erreur en C++ mais pas en C:
typedef struct nodes
{
int data;
struct node *next;
}node;
Il donne le message d'erreur suivant en C++.
/home/DS cpp/linkedlist.cpp|10|error: conflicting declaration ‘typedef struct nodes node’|
/home/DS cpp/linkedlist.cpp|9|error: ‘struct node’ has a previous declaration as ‘struct node’|
||=== Build failed: 2 error(s), 0 warning(s) (0 minute(s), 0 second(s)) ===|
Pour qu'il fonctionne en C++, je dois le changer à cela:
typedef struct node
{
int data;
struct node *next;
}node;
Je ne comprends pas pourquoi ce qui se passe, je veux savoir l'ordre d'exécution en C et C++ afin que je puisse comprendre.
source d'informationauteur Achyut Rastogi
Vous devez vous connecter pour publier un commentaire.
Nous allons analyser votre code un peu:
Il déclare et définit
struct nodes
un type avec deux membres, et déclare un alias de type si nous pouvons nous référer à elle seule commenode
.Maintenant, en C++, la déclaration d'un membre de
struct node *next
automatiquement de l'avant-déclare un type appelénode
. Qui puis est en conflit avec votretypedef
ciblenode
: c'est comme si vous êtes en essayant de donner deux types du même nom.En C, il n'y a pas de conflit, parce que le type appelé
node
peut en fait que d'être appeléstruct node
.Le deuxième extrait de travaillé, puisque, lors de l'analyse de la déclaration du membre de
struct node
existe déjà, pas de nouveau type est à l'avant-déclarée, il ... et depuis tout ce que vous êtes, puis de le faire est de renommer dans le mêmetypedef
déclaration, le C++ n'est pas vraiment de soins, sachant que c'est tout de même type (struct T
estT
; la différence est dans la syntaxe, pas de nom).Bien sûr, en C++, c'est tout à fait discutable et il vous suffit d'écrire:
Vous n'avez pas besoin de
typedef
-loin de la élaboré de type spécificateur destruct
.Le C de l'exemple que vous avez donné doit être une erreur. Vous utilisez un nom de balise (
node
) que vous n'avez pas défini avecstruct node
.Compte tenu de ces deux choix, le second est celui à utiliser. Je préfère un peu d'économie:
En C ou C++, les noms des balises ont leur propre espace de noms, donc il n'y a pas de problème avec l'utilisation du même nom de la balise et de la définition de type nom. En C, cela vous permet d'utiliser soit
node_t
oustruct node_t
pour se référer à ce type struct. C++ va rechercher les noms de balise pour un nom de type, si un type déclaré de nom n'existe pas, de sorte que la double définition n'est pas nécessaire, mais ne fait pas de mal.Dans les deux langues, l'explicite
struct node_t
version est nécessaire à tout moment avant que le type est complètement défini, de sorte que toute auto-référence, et de toute en avant les références à utiliser lestruct
version. Je préfère ce dans les fichiers d'en-tête, surtout parce qu'il réduit les problèmes avec l'ordre du#include
directives.PS: Ce ne travail dans les deux langues (voir LRIO de réponse pour les pointeurs en C++11) et a été utilisé assez bilingue et même pur C++ fichiers d'en-tête qu'il est peu probable qu'il disparaisse bientôt) c'est donc une approche très simple qui fonctionne dans les deux langues.