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