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

Leopoldo Ghielmetti leopoldo.ghielmetti at a3.epfl.ch
Tue Apr 15 11:10:47 CEST 2008


Si ça ne te fais rien si c'est moi qui te répond. :-)

On Tue, 2008-04-15 at 02:37 +0200, Marc Mongenet wrote:
> Je n'ai été au point avec cette subtilité qu'en relisant
> le K&R suite aux discussions de la subtilité de C n° 2.
> Autrement dit, j'ai souvent déclaré des structures
> sans vraiment comprendre ce que je faisais :
> je me contentais de constater que ça marchait,
> ce qui est pourtant fort risqué en C...
> Mais pour une fois, le risque apparaît très faible :
> je n'ai jamais rencontré de problème (de portabilité
> ou autre) malgré ma négligence.
> Ce n'est cependant pas une raison pour bidouiller
> plus longtemps !
> 
> Voici donc le Quiz :
> Parmi les deux exemples suivants, un seul compile
> (avec gcc -c -ansi -pedantic). Lequel ? Pourquoi ?
> 
> ----------------------- 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.
Par contre on a un beau warning si on ajoute l'option -Wshadow, ce qui
confirme mon hypothèse:
ex2.c: In function ‘f’:
ex2.c:6: warning: declaration of ‘v’ shadows a global declaration
ex2.c:1: warning: shadowed declaration is here

Pour ma part j'évite les conditions de shadowing comme de la peste. Ça
marche bien tant qu'on ne touche à rien dans le code, mais ça devient
vite inmaintenable car il suffit de changer quelque ligne de code et ça
foire vite fait.

> NB : La seule différence est la position du « struct s; ».

C'est tout la dessus que ça se joue.

ciao, Leo




More information about the gull mailing list