Re: [gull] Subtilité de C n° 2 : type de retour de malloc
Marc Mongenet
marc at mongenet.ch
Thu Apr 3 19:28:13 CEST 2008
2008/4/3, Daniel Cordey <dc at mjt.ch>:
> On Thursday 03 April 2008, Marc Mongenet wrote:
>
> > Je me réponds à moi-même pour complèter mon message
> > initial et clore cette subtilité n°2.
> > NB : J'utilise gcc-3.3, car gcc 4 a une extension non standard
> > qui reconnait malloc comme une fonction builtin, et donne des
> > messages d'erreurs particuliers.
>
> Ah, mais j'espere que le malloc utilise est bien celui de la libc... oui ?
>
Je ne sais pas. Il y a de la documentation sur les builtin, mais je ne
l'ai pas lue.
http://gcc.gnu.org/onlinedocs/gcc-4.1.2/gcc/Other-Builtins.html
>
> > Fichier f3.c (buggué !) :
> > ------
> > void f() { int *p = (int*)malloc(sizeof *p); }
> > ------
>
>
> Commentaire de nouveau purement semantique (et pseudo-syntaxique)...
>
> utiliser '*p' dans le sizeof, pour l'assignation d'une variable dans
> sa "definition", alors que cette "definition" n'est pas "completed"... me
> parait limite... C'est peut-etre un cas particulier ou l'assignation
> determine la "completion" de la "definition"...
Bien vu, je ne m'en était pas rendu compte !
Et c'est vrai que le cas est assez limite pour me donner un doute...
Je compulse le K&R... voilà :
Le "lexical scope" débute à la fin du "declarator" (chap. A11.1)
Et d'après la grammaire C donnée dans le chap. A8 :
init-declarator:
declarator
declarator = initializer
La fin du "declarator" se trouve bien devant le '=' qui précède
l''"initializer", ouf ! ;-)
> Par contre, comme je ne peux pas definir un element de structure comme etant
> un pointeur sur son propre type, je suis oblige d'utiliser 'void *'.
>
> /* marche pas (normal !) */
> struct {
> struct toto *myself;
> ...
> } toto;
>
> Ceci s'explique puisque la "definition" n'est pas complete avant la reference.
Si si, ça marche très bien !
On peut même écrire (exemple du K&R 2nd edition, p. 140.) :
struct t {
struct s *p;
};
struct s {
struct t *q;
}
Le pointeur p est un pointeur sur type incomplet.
Ca sert justement à déclarer les structures qui pointent
récursivement sur elle-mêmes. Ca existe depuis plus
longtemps que void lui-même.
On n'a évidemment pas le droit de déréférencer un tel
pointeur tant que le type est incomplet (sinon on a
une erreur du genre : "error: dereferencing pointer to
incomplete type".
En fait, on a le droit d'écrire
struct foo_bar;
sans que foo_bar soit déjà déclaré. C'est une déclaration
de type incomplet. D'après mon K&R C :
"Objects with an incomplete structure or union type may
be mentioned in contexts where their size is not needed,
for example in declarations (not definitions), for specifying
a pointer, or for creating a typedef, but not otherwise.
>
> /* marche */
> struct {
> void *myself; /* et toc :-) */
Oui mais c'est très mal d'utiliser un pointeur void. :-p
--
Marc Mongenet
Creator of the Web 2 Markup Language
http://w2ml.com
More information about the gull
mailing list