‘CHAR_WIDTH’ undeclared
Podczas próby skompilowania tego prostego programu pojawia się błąd
:
#include <stdio.h>
#include <limits.h>
int main()
{
printf("CHAR_BIT = %d\n", CHAR_BIT);
printf("CHAR_WIDTH = %d\n", CHAR_WIDTH);
return (0);
}
z
gcc ./show_char_width.c -o show_char_width
i gcc: GNU C17 (Ubuntu 8.3.0-6ubuntu1) wersja 8.3.0 (x86_64-linux-gnu) skompilowana przez GNU C wersja 8.3.0, GMP wersja 6.1.2, MPFR wersja 4.0.2, MPC wersja 1.1.0 , wersja isl isl-0.20-GMP, jądro: 5.0.0-37-generic.
Jak wspomniano tutaj CHAR_WIDTH należy zdefiniować w limit.h, który jest zawarty w moim programie. Dlaczego więc otrzymuję ten błąd?
Z -v
opcją stwierdziłem, że biblioteka będzie przeszukiwana w tych katalogach:
#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 zawiera limit.h, który obejmuje syslimits.h z tego samego katalogu, który z kolei zawiera kolejne limity.h, który z mojego zrozumienia powinien znajdować się w katalog / usr / include.
Makro CHAR_WIDTH jest rzeczywiście zdefiniowane w tych plikach, ale pod pewnymi warunkami, które przekraczają moją rzeczywistą wiedzę.
Warunki, które do tej pory znalazłem to:
/* 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
i :
#ifdef __STDC_WANT_IEC_60559_BFP_EXT__
/* TS 18661-1 widths of integer types. */
# undef CHAR_WIDTH
# define CHAR_WIDTH __SCHAR_WIDTH__
Dlatego potrzebuję twojej pomocy.
Uwaga: pojawia się ten sam błąd ze wszystkimi innymi makrami opisanymi w A.5.1, w szczególności: SCHAR_WIDTH, INT_WIDTH, LONG_WIDTH itp.
__STDC_WANT_IEC_60559_BFP_EXT__
lub przekaż to wierszem poleceńCHAR_BIT
8, co oznacza, żeCHAR_WIDTH
musi być również 8 w systemach POSIX.#define
wcześniej#include
?Odpowiedzi:
CHAR_WIDTH
nie jest standardem, podobnie jak inne*_WIDTH
makra, ale szerokość typu znaku musi być taka sama jak wCHAR_BIT
każdym przypadku *.Jeśli chodzi o
*_WIDTH
makra, nie są one absolutnie potrzebne, ponieważ można je obliczyć w czasie kompilacji z maksymalnej wartości odpowiedniego typu bez znaku, tzn. Możesz mieć ciąg#define WIDTH_FROM_UNSIGNED_MAX(UnsignedMax)
rozwijany do wyrażenia stałego liczb całkowitych, które można również stosować w warunkach warunkowych preprocesora (#if
), chociaż implementacje są nieco niejasne (patrz Czy jest jakiś sposób na obliczenie szerokości typu liczby całkowitej w czasie kompilacji? ), np .:Niektóre osoby tak robią
CHAR_BIT * sizeof(integer_type)
, ale to nie jest przenośne , ponieważ zakłada,integer_type
że nie ma bitów wypełniających (zwykle nie, ale teoretycznie może je mieć) i nie może używać go również w#if
warunkowym.* Niestety, aby zebrać te informacje, musisz przeskoczyć cały standard:
Szerokość typu liczb całkowitych jest (nieco pośrednio) zdefiniowana jako liczba bitów niepochodzących ( 6.2.6.2p6 ).
6.2.6.2p2 mówi,
signed char
że nie ma żadnych bitów wypełniających. Ze względu na to, w jaki sposób liczby całkowite mogą być reprezentowane w C ( 6.2.6.2p2 ), oznacza to, żeunsigned char
nie mogą mieć również żadnych bitów wypełniających, a ponieważchar
muszą mieć takie same ograniczenia jak jedensigned char
lubunsigned char
( 5.2.4.2.1p2 ), a jednocześnie mieć tę samąsizeof
wartość ( mianowicie 1, 6.5.3.4p4 ), zwykłychar
nie może mieć także żadnych bitów dopełniających, a więcCHAR_BIT
== szerokość (char
|signed char
|unsigned char
) .źródło