Recibo el error
‘CHAR_WIDTH’ undeclared
cuando intento compilar este sencillo programa:
#include <stdio.h>
#include <limits.h>
int main()
{
printf("CHAR_BIT = %d\n", CHAR_BIT);
printf("CHAR_WIDTH = %d\n", CHAR_WIDTH);
return (0);
}
con
gcc ./show_char_width.c -o show_char_width
y gcc: GNU C17 (Ubuntu 8.3.0-6ubuntu1) versión 8.3.0 (x86_64-linux-gnu) compilado por GNU C versión 8.3.0, GMP versión 6.1.2, MPFR versión 4.0.2, MPC versión 1.1.0 , versión isl isl-0.20-GMP, kernel: 5.0.0-37-generic.
Como se indica aquí, CHAR_WIDTH debe definirse en los límites. H, que se incluye en mi programa. Entonces, ¿por qué me sale este error?
Con la -v
opción encontré que la biblioteca se buscará en esos directorios:
#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 contiene un limit.h que incluye syslimits.h desde el mismo directorio que a su vez incluye los siguientes límites.h, que según tengo entendido debería estar ubicado en el directorio / usr / include.
La macro CHAR_WIDTH está definida en esos archivos, pero en algunas condiciones que exceden mi conocimiento real.
Las condiciones que encontré hasta ahora son:
/* 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
y:
#ifdef __STDC_WANT_IEC_60559_BFP_EXT__
/* TS 18661-1 widths of integer types. */
# undef CHAR_WIDTH
# define CHAR_WIDTH __SCHAR_WIDTH__
Por eso necesito tu ayuda.
Nota: obtengo el mismo error con todas las demás macros descritas en A.5.1, en particular: SCHAR_WIDTH, INT_WIDTH, LONG_WIDTH, etc.
__STDC_WANT_IEC_60559_BFP_EXT__
o pasarlo por línea de comandoCHAR_BIT
ser 8, lo que debería significarCHAR_WIDTH
que también debe ser 8 en los sistemas POSIX.#define
antes de la#include
?Respuestas:
CHAR_WIDTH
no es estándar, ni ninguna otra*_WIDTH
macro, pero el ancho de un tipo de caracteres debe ser el mismo que el deCHAR_BIT
todos modos *.En cuanto a las
*_WIDTH
macros en general, no son estrictamente necesarias, ya que son computables en tiempo de compilación a partir del valor máximo del tipo sin signo correspondiente, es decir, puede tener un#define WIDTH_FROM_UNSIGNED_MAX(UnsignedMax)
que se expande a una expresión constante entera que también se puede usar en preprocesadores condicionales (#if
), aunque las implementaciones son un poco oscuras (consulte ¿Hay alguna forma de calcular el ancho de un tipo entero en tiempo de compilación? ), por ejemplo:Algunas personas simplemente lo hacen
CHAR_BIT * sizeof(integer_type)
, pero eso no es estrictamente portátil , porque suponeinteger_type
que no tiene bits de relleno (generalmente no los tiene, pero en teoría puede tenerlos), y tampoco puede usarlo en#if
condicionales.* Desafortunadamente, para obtener esta información, debe saltar todo el estándar:
El ancho de un tipo entero se define (ligeramente indirectamente) como el número de sus bits sin relleno ( 6.2.6.2p6 ).
6.2.6.2p2 dice
signed char
que no tiene bits de relleno. Debido a cómo los números enteros se pueden representar en C ( 6.2.6.2p2 ), eso implica queunsigned char
tampoco puede tener ningún bit de relleno, y dado quechar
debe tener los mismos límites que unosigned char
ounsigned char
( 5.2.4.2.1p2 ) mientras tiene el mismosizeof
valor ( a saber, 1, 6.5.3.4p4 ), un planochar
tampoco puede tener bits de relleno, y por lo tantoCHAR_BIT
== ancho de (char
|signed char
|unsigned char
) .fuente