J'obtiens l'erreur
‘CHAR_WIDTH’ undeclared
lorsque j'essaie de compiler ce programme simple:
#include <stdio.h>
#include <limits.h>
int main()
{
printf("CHAR_BIT = %d\n", CHAR_BIT);
printf("CHAR_WIDTH = %d\n", CHAR_WIDTH);
return (0);
}
avec
gcc ./show_char_width.c -o show_char_width
et gcc: GNU C17 (Ubuntu 8.3.0-6ubuntu1) version 8.3.0 (x86_64-linux-gnu) compilé par GNU C version 8.3.0, GMP version 6.1.2, MPFR version 4.0.2, MPC version 1.1.0 , version isl isl-0.20-GMP, noyau: 5.0.0-37-générique.
Comme indiqué ici, CHAR_WIDTH doit être défini dans limits.h qui est inclus dans mon programme. Alors pourquoi j'ai cette erreur?
Avec l' -v
option, j'ai trouvé que la bibliothèque sera recherchée dans ces répertoires:
#include "..." search starts here:
#include <...> search starts here:
/usr/lib/gcc/x86_64-linux-gnu/8/include
/usr/local/include
/usr/lib/gcc/x86_64-linux-gnu/8/include-fixed
/usr/include/x86_64-linux-gnu
/usr/include
/ usr / lib / gcc / x86_64-linux-gnu / 8 / include-fixed contient un limits.h qui inclut syslimits.h du même répertoire qui à son tour inclut le prochain limits.h, qui d'après ma compréhension devrait se trouver dans le répertoire / usr / include.
La macro CHAR_WIDTH est en effet définie dans ces fichiers mais sous certaines conditions qui dépassent mes connaissances réelles.
Les conditions que j'ai trouvées jusqu'à présent sont les suivantes:
/* The integer width macros are not defined by GCC's <limits.h> before
GCC 7, or if _GNU_SOURCE rather than
__STDC_WANT_IEC_60559_BFP_EXT__ is used to enable this feature. */
#if __GLIBC_USE (IEC_60559_BFP_EXT)
# ifndef CHAR_WIDTH
# define CHAR_WIDTH 8
# endif
et :
#ifdef __STDC_WANT_IEC_60559_BFP_EXT__
/* TS 18661-1 widths of integer types. */
# undef CHAR_WIDTH
# define CHAR_WIDTH __SCHAR_WIDTH__
Voilà pourquoi j'ai besoin de votre aide.
Remarque: j'obtiens la même erreur avec toutes les autres macros décrites en A.5.1 notamment: SCHAR_WIDTH, INT_WIDTH, LONG_WIDTH, etc.
__STDC_WANT_IEC_60559_BFP_EXT__
ou passer par ligne de commandeCHAR_BIT
être 8, ce qui devrait signifier qu'ilCHAR_WIDTH
doit également être 8 sur les systèmes POSIX.#define
avant le#include
?Réponses:
CHAR_WIDTH
n'est pas standard, ni aucune autre*_WIDTH
macro, mais la largeur d'un type de caractère doit être la même que deCHAR_BIT
toute façon *.Quant aux
*_WIDTH
macros en général, elles ne sont pas strictement nécessaires car elles sont calculables au moment de la compilation à partir de la valeur maximale du type non signé correspondant, c'est-à-dire que vous pouvez avoir un#define WIDTH_FROM_UNSIGNED_MAX(UnsignedMax)
qui se développe en une expression constante entière qui est également utilisable dans les conditions préalables du préprocesseur (#if
), bien que les implémentations soient un peu obscures (voir Existe - t-il un moyen de calculer la largeur d'un type entier au moment de la compilation? ), par exemple:Certaines personnes le font
CHAR_BIT * sizeof(integer_type)
, mais ce n'est pas strictement portable , car il suppose qu'ilinteger_type
n'a pas de bits de remplissage (il n'en a généralement pas mais théoriquement il peut les avoir), et ne peut pas non plus l'utiliser dans des#if
conditions.* Malheureusement, pour glaner ces informations, vous devez sauter partout dans la norme:
La largeur d'un type entier est (légèrement indirectement) définie comme le nombre de ses bits non remplis ( 6.2.6.2p6 ).
6.2.6.2p2 dit qu'il
signed char
n'a pas de bits de remplissage. En raison de la façon dont les entiers peuvent être représentés en C ( 6.2.6.2p2 ), cela implique qu'ilsunsigned char
ne peuvent pas non plus avoir de bits de remplissage, et qu'ilschar
doivent avoir les mêmes limites que l'unsigned char
ou l' autreunsigned char
( 5.2.4.2.1p2 ) tout en ayant la mêmesizeof
valeur ( à savoir 1, 6.5.3.4p4 ), une plainechar
ne peut pas non plus avoir de bits de remplissage, et doncCHAR_BIT
== largeur de (char
|signed char
|unsigned char
) .la source