Pourquoi les fonctions ctype prennent-elles int mais veulent-elles un type char / EOF non signé?

J’utilise gcc (Ubuntu / Linaro 4.6.1-9ubuntu3) 4.6.1

La page de isalnum() de isalnum() dit:

 SYNOPSIS #include  int isalnum(int c); 

Cependant, il dit aussi:

Ces fonctions vérifient si c, qui doit avoir la valeur d’un caractère non signé ou EOF, …

J’ai trouvé que isalnum() exploserait pour de très grandes valeurs int positives (ou négatives) (mais il gère toutes short int valeurs short int ).

Est-ce que la page de manuel disant que l’int transmis doit avoir la valeur d’un caractère unsigned char car les auteurs de la bibliothèque C se isalnum() le droit d’implémenter isalnum() de manière à ne pas gérer toutes les valeurs int sans exploser?

La norme C en dit autant …

Dans ISO / IEC 9899: 1999 (l’ancienne norme C), il est écrit:

§7.4 Traitement des caractères

L’en-tête déclare plusieurs fonctions utiles pour la classification et le mappage de caractères. Dans tous les cas, l’argument est un entier dont la valeur doit pouvoir être représentée sous la forme d’un caractère non signé ou doit être égale à la valeur de la macro EOF. Si l’argument a une autre valeur, le comportement est indéfini.

( J’ai omis une note de bas de page. ) C89 et C11 disent à peu près la même chose.

Une implémentation courante consiste à utiliser un tableau décalé de 1 – une variation sur le thème de:

 int _CtypeBits[257] = { ... }; #define isalpha(c) (_Ctype_bits[(c)+1]&_ALPHA); 

Tant que c est dans la plage d’entiers qu’un caractère unsigned char peut stocker (et qu’il y a 8 bits par caractère, EOF est -1 et que l’initialisation est correcte), alors cela fonctionne à merveille. Notez que le développement de macro utilise uniquement l’argument une fois, ce qui est une autre exigence de la norme. Mais si vous transmettez des valeurs aléatoires en dehors de la plage stipulée, vous accédez à la mémoire aléatoire (ou, au moins, à la mémoire non initialisée pour contenir les informations correctes).