[gull] Subtilité de C n° 4 : déclaration de struct

Leopoldo Ghielmetti leopoldo.ghielmetti at a3.epfl.ch
Thu Apr 17 15:59:37 CEST 2008


Il giorno mer, 16/04/2008 alle 21.31 +0200, Marc Mongenet ha scritto:
> Le 15/04/08, Leopoldo Ghielmetti<leopoldo.ghielmetti at a3.epfl.ch> a écrit :
> > Si ça ne te fais rien si c'est moi qui te répond. :-)
> >
> 
> Non, non. ;-)
> 
> >  On Tue, 2008-04-15 at 02:37 +0200, Marc Mongenet wrote:
> >  >
> >  > ----------------------- ex1.c
> >  > struct s { int i; } v;
> >  > struct s;
> >  >
> >  > void f(void) {
> >  >       struct ps { struct s *p; } ps;
> >  >       struct s { int j; } v;
> >  >       ps.p = &v;
> >  >       ps.p->j = 0;
> >  > }
> >  >
> >  > ----------------------- ex2.c
> >  > struct s { int i; } v;
> >  >
> >  > void f(void) {
> >  >       struct s;
> >  >       struct ps { struct s *p; } ps;
> >  >       struct s { int j; } v;
> >  >       ps.p = &v;
> >  >       ps.p->j = 0;
> >  > }
> >  > -----------------------
> >
> >
> > Après compilation l'erreur paraît évident.
> >  Dans le premier cas la structure ps utilise la structure s déclarée en
> >  dehors de f qui est incompatible avec la variable v et qui ne possède
> >  donc pas de membre j, d'où les erreurs:
> >  ex1.c: In function 'f':
> >  ex1.c:7: warning: assignment from incompatible pointer type
> >  ex1.c:8: error: 'struct s' has no member named 'j'
> >
> >  Dans le second cas on redéclare une structure s locale à la fonction f
> >  qui sera donc identique à la structure s utilisée par v, donc tout
> >  compile comme un charme.
> 
> Dans les deux cas on redéclare une structure s locale à la fonction f. :-)
> Pourtant dans un cas la déclaration du pointeur p fait référence à la
> structure s déjà déclarée, et pas dans l'autre cas... Troublant, n'est-ce
> pas ? ;-)

Oui, en effet, je me suis mal expliqué. La structure s est de toute
façon redéclarée.
Les deux codes seraient par contre identiques si la structure ps était
déclarée juste après la structure s

Et non, je ne trouve pas ça trop troublant. Le struct s est une
déclaration avancée de la "future" déclaration de la structure s. Dans
le premier code cette déclaration n'a aucune influence car la structure
s vient d'être déclarée, dans le deuxième cas elle annonce la prochaine
déclaration de la structure s interne à la fonction.
C'est donc logique que ps utilise dans le premier cas la première
structure et dans le deuxième cas la deuxième.

Tu aurais aussi un joli effet si tu ajoutais la déclaration suivante
juste après la déclaration de ps et avant la declaration de la structure
s:
int ssize = sizeof(struct s);

Je n'ai pas vérifié en compilant la chose mais j'imagine que dans le
premier cas ça marche et ssize prend la valeur correspondante à la
taille de la structure s, dans le deuxième cas ça plante à la
compilation car la structure s n'a pas encore été déclarée.

> >  > NB : La seule différence est la position du « struct s; ».
> >
> > C'est tout la dessus que ça se joue.
> 
> Oui. La description précise de ce que fait ce « struct s; » est
> d'ailleurs assez tordue.

Dans le premier cas rien (car il confirme que la struct s existe bel et
bien), dans le deuxième il annonce la future déclaration de la structure
s. Ça ne me parait pas si tordu que ça.

ciao, Leo




More information about the gull mailing list