Référence du fichier stddef.h


Description détaillée

Cet entête contient des définitions diverses. La différence avec l'autre entête fourre-tout (<stdlib.h>), c'est que stddef.h doit être disponible même pour les implémentations sans environnement d'exécution (freestanding).


Macros

#define NULL
 pointeur nul
#define offsetof(type, member)
 décalage d'un membre

Définition de type

typedef __signed ptrdiff_t
 différence entre pointeurs.
typedef __unsigned size_t
 taille des objets
typedef __integral wchar_t
 caractère large


Documentation des macros

#define NULL

Cette macro contient une constante de pointeur nul. Des valeurs populaires sont 0, 0L, (void*)0.

Le fait que la notation du pointeur nul soit 0 ou des variantes n'impose pas que sa représentation soit la même que celle de l'entier 0. Autrement dit rien n'impose que (void*)i == (void*)0 même si la variable entière i contient 0, mais les implémentations utilisant cette latitude sont rares.

Note:
Traditionnellement, la valeur de NULL était 0. Les autres valeurs résultent du désir de continuer à faire fonctionner le code passant NULL à une fonction variadique quand les pointeurs et les entiers n'ont pas la même taille. Le problème est qu'il n'y a pas d'indication du type des derniers argument des fonctions variadiques, les règles du C rendent donc indéfini le passage d'arguments d'un autre type que celui récupéré. Passer 0 quand on attend un pointeur ne pose en pratique pas de problèmes tant que les entiers et les pointeurs ont la même taille. Si ce n'est pas le cas par contre, il y aura problème.
Définir NULL comme (void*)0 permet de passer NULL comme pointeur aux fonctions variadiques tant que les void* n'ont pas une représentation différente des autres pointeurs, mais casse le code qui utilise NULL quand il faut un entier.

Définir NULL comme 0L permet de passer NULL comme pointeur aux fonctions variadique si les pointeurs et les long ont la même taille, et permet de faire fonctionner le code qui utilise aussi NULL dans des contextes demandant un entier (en particulier à la place de '\0').

Donc pour être conforme, il ne faut pas utiliser NULL dans des contextes demandant un entier et il faut le caster dans le pointeur adéquat dans les appels à des fonctions variadiques. La première erreur est rare -- les implémentations utilisant (void*)0 sont courantes et signalent l'erreur à la compilateur. La seconde est beaucoup plus fréquente, les implémentations où elle entraîne un comportement erroné sont beaucoup plus rares et l'erreur n'est pas détectée à la compilation.

Note:
Le C++ ne permet pas la définition (void*)0.

#define offsetof ( type,
member   ) 

Donne le décalage en bytes sous forme d'un size_t du membre member de type, qui doit être une structure.


Documentation des définition de type

typedef __signed ptrdiff_t

Ce type entier signé est capable de contenir la différence entre deux pointeurs.

typedef __unsigned size_t

Ce type entier non signé est capable de contenir la taille des objets.

typedef __integral wchar_t

Ce type entier est capable de représenter tous les codes pour le charset le plus étendu parmi les charsets des locales supportées.


Copyright © 2008 -- 2009 Jean-Marc Bourguet Accueil Pages sur le C