[gull] Subtilité de C n° 2 : type de retour de malloc

Leopoldo Ghielmetti leopoldo.ghielmetti at a3.epfl.ch
Thu Apr 3 10:12:22 CEST 2008


On Thu, 2008-04-03 at 01:49 +0200, Marc Mongenet wrote:
> Le 02/04/08, Leopoldo Ghielmetti<leopoldo.ghielmetti at a3.epfl.ch> a écrit :
> >  > L'opérateur sizeof retourne le nombre de bytes de son opérande ;
> >  > c'est sa raison d'être. Appliqué à une structure, il retourne la taille
> >  > de la structure, incluant les éventuels padding à l'intérieur et à la
> >  > fin de la structure.
> >
> >
> > Ce n'est pas ce que j'ai constaté, j'ai même remarqué que:
> >  struct toto *t;
> >  int i = sizeof(*t);
> >  int j = sizeof(struct toto);
> >
> >  on a i >= j
> >
> >  D'ou j'en ai déduit que sizeof(struct toto) retourne la taille de la
> >  structure sans le padding tandis que sizeof(*t) retourne la taille
> >  exacte utilisée par la structure pointée par t, donc la taille avec le
> >  pad.
> 
> Et bien... je dois avouer que ne vois pas de moyen pour obtenir
> un i différent de j sans abus de macros ni utilisation d'une extension
> non standard bizarroïde du compilateur.

Oui, c'est ce que je pensais aussi avant de me retrouver dans la
situation ou les deux étaient différents.

> Même un bug du compilateur me paraît tout à fait improbable,
> car il ne compilerait pratiquement aucun programme C
> correctement.

Effectivement il se peut qu'il s'agissait d'un bug du compilateur.

> En effet, si i et j pouvaient être différent, rien que l'utilisation
> classique du sizeof pour calculer le nombre d'éléments d'un
> tableau risquerait de donner des résultats insensés...
> #define NKEYS (sizeof keytab / sizeof(struct key))
> #define NKEYS (sizeof keytab / sizeof keytab[0])
> NB : Ces deux écritures possibles sont présentées dans le
> K&R, chap. 6.3. Je trouve toujours dingue comme le K&R
> contient toute la sagesse de C en 1 cm d'épaisseur ! :-D
> 
> L'allocation d'un tableau de n structures par cet idiome très
> courant pourrait aussi causer des corruptions de mémoire :
> tab = malloc(n * sizeof(struct s));
> 
> Cela dit, le K&R date un peu, même mon édition revue pour
> ANSI C89. Mais une publication récente comme le draft
> ISO/IEC 9899:TC3 est aussi explicite sur sizeof et le padding :
> "The size is determined from the type of the operand. [...]
> When applied to an operand that has structure or union type,
> the result is the total number of bytes in such an object,
> including internal and trailing padding."

Oui, je suis tout à fait d'accord que normalement les deux écritures
devraient être la même chose, mais en pratique je suis tombé sur quelque
cas ou ils n'étaient pas la même chose.

> Pour en revenir au K&R, le chap 8.7 présente une implémentation
> de malloc qui n'utilise ni conversion de pointeur en entier, ni
> opération sur les bits, et arrive pourtant à retourner des pointeurs
> alignés d'une manière remarquablement portable ! Un vrai petit
> bijou. ;)
> 
> > En plus il y a certains warnings qu'on ne peut
> > pas éviter à cause de bizarreries dans la librairie standard (p.e.
> > l'utilisation d'un void* à la place d'un const void*
> 
> Ah oui, c'est une plaie que les bibliothèques qui utilisent mal,
> ou pas, les const.

ciao, Leo




More information about the gull mailing list