CHAR_WIDTH tidak dideklarasikan

9

Saya mendapatkan kesalahan ‘CHAR_WIDTH’ undeclared saat mencoba mengompilasi program sederhana ini:

#include <stdio.h>
#include <limits.h>

int main()
{
  printf("CHAR_BIT = %d\n", CHAR_BIT);
  printf("CHAR_WIDTH = %d\n", CHAR_WIDTH);
  return (0);
}

dengan

gcc ./show_char_width.c -o show_char_width

dan gcc: GNU C17 (Ubuntu 8.3.0-6ubuntu1) versi 8.3.0 (x86_64-linux-gnu) dikompilasi oleh GNU C versi 8.3.0, versi GMP 6.1.2, versi MPFR 4.0.2, versi MPFR 4.0.2, versi MPC 1.1.0 , versi isl isl-0.20-GMP, kernel: 5.0.0-37-generic.

Seperti yang dinyatakan di sini, CHAR_WIDTH harus didefinisikan dalam limit.h yang termasuk dalam program saya. Jadi mengapa saya mendapatkan kesalahan ini?

Dengan -vopsi yang saya temukan bahwa perpustakaan akan dicari di direktori tersebut:

#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-fix berisi batasan.h yang menyertakan syslimits.h dari direktori yang sama yang pada gilirannya menyertakan batasan berikutnya.h, bahwa dari pemahaman saya harus ditempatkan di direktori / usr / include.

Makro CHAR_WIDTH memang didefinisikan dalam file-file itu tetapi dalam beberapa kondisi yang melebihi pengetahuan saya yang sebenarnya.

Kondisi yang saya temukan sampai sekarang adalah:


/* 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

dan:

#ifdef __STDC_WANT_IEC_60559_BFP_EXT__
/* TS 18661-1 widths of integer types.  */
# undef CHAR_WIDTH
# define CHAR_WIDTH __SCHAR_WIDTH__

Itu sebabnya saya butuh bantuan Anda.

Catatan: Saya mendapatkan kesalahan yang sama dengan semua makro lain yang dijelaskan dalam A.5.1 terutama: SCHAR_WIDTH, INT_WIDTH, LONG_WIDTH, dll.

Pliski
sumber
Kondisi seperti apa?
LP
1
@ LP: mungkin beberapa yang OP tidak mengerti -> " melebihi pengetahuan saya yang sebenarnya. "
alk
2
Setelah diedit. tentukan __STDC_WANT_IEC_60559_BFP_EXT__atau lewati dengan baris perintah
piringan hitam
1
FWIW, POSIX CHAR_BITharus 8, yang seharusnya CHAR_WIDTHjuga berarti 8 pada sistem POSIX.
Andrew Henle
4
@pliski kan #definesebelum #include?
LegendofPedro

Jawaban:

5

CHAR_WIDTHtidak standar, *_WIDTHmakro juga tidak ada , tetapi lebar tipe karakter harus sama dengan CHAR_BIT*.

Adapun *_WIDTHmakro secara umum, mereka tidak benar-benar diperlukan karena mereka kompilasi-waktu-dihitung dari nilai maksimum dari jenis unsigned yang sesuai, yaitu, Anda dapat memiliki #define WIDTH_FROM_UNSIGNED_MAX(UnsignedMax)yang memperluas ke ekspresi konstanta integer yang juga dapat digunakan dalam kondisi preprocessor ( #if), meskipun implementasi sedikit tidak jelas (lihat Apakah ada cara untuk menghitung lebar tipe integer pada waktu kompilasi? ), misal:

#define WIDTH_FROM_UNSIGNED_MAX(UnsignedMax) POW2_MINUS1_BITS_2039(UnsignedMax)
/* Number of bits in inttype_MAX, or in any (1<<k)-1 where 0 <= k < 2040 */
#define POW2_MINUS1_BITS_2039(X) ((X)/((X)%255+1) / 255%255*8 + 7-86/((X)%255+12))

//compile-time test it, assuming uint{8,16,32,64}_t exist
#include <inttypes.h>
#if WIDTH_FROM_UNSIGNED_MAX(UINT8_MAX) != 8
    #error
#endif
#if WIDTH_FROM_UNSIGNED_MAX(UINT16_MAX) != 16
    #error
#endif
#if WIDTH_FROM_UNSIGNED_MAX(UINT32_MAX) != 32
    #error
#endif
#if WIDTH_FROM_UNSIGNED_MAX(UINT64_MAX) != 64
    #error
#endif

Beberapa orang hanya melakukannya CHAR_BIT * sizeof(integer_type), tetapi itu tidak sepenuhnya portabel , karena mengasumsikan integer_typetidak memiliki bit padding (biasanya tidak tetapi secara teoritis dapat memilikinya), dan tidak dapat menggunakannya dalam #ifkondisi baik.


* Sayangnya, untuk mendapatkan info ini, Anda perlu melompati semua standar:

Lebar tipe integer (sedikit tidak langsung) didefinisikan sebagai jumlah bit nonpaddingnya ( 6.2.6.2p6 ).

6.2.6.2p2 mengatakan signed chartidak memiliki bit bantalan. Karena bagaimana bilangan bulat dapat direpresentasikan dalam C ( 6.2.6.2p2 ), itu menyiratkan unsigned chartidak dapat memiliki bit padding baik, dan karena charharus memiliki batas yang sama dengan signed charatau unsigned char( 5.2.4.2.1p2 ) sementara memiliki nilai yang sama sizeof( yaitu 1, 6.5.3.4p4 ), sebuah dataran chartidak dapat memiliki bit padding, dan = = CHAR_BIT lebar ( char| signed char| unsigned char) .

PSkocik
sumber