CHAR_WIDTH bildirilmedi


9

‘CHAR_WIDTH’ undeclared Bu basit programı derlemeye çalıştığımda hatayı alıyorum :

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

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

ile

gcc ./show_char_width.c -o show_char_width

ve gcc: GNU C sürüm 8.3.0, GMP sürüm 6.1.2, MPFR sürüm 4.0.2, MPCR sürüm 4.0.0 tarafından derlenen GNU C17 (Ubuntu 8.3.0-6ubuntu1) sürüm 8.3.0 (x86_64-linux-gnu) , isl sürümü isl-0.20-GMP, çekirdek: 5.0.0-37-jenerik.

Belirtildiği gibi burada CHAR_WIDTH benim programına dahil edilir limits.h içinde tanımlanmalıdır. Peki neden bu hatayı alıyorum?

-vSeçeneği ile kütüphane bu dizinlerde aranacak bulundu:

#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, syslimits.h'yi içeren bir limit.h içerir ve bu da bir sonraki sınırları içerir. h, benim anladığım kadarıyla içinde bulunması gereken / usr / include dizini.

CHAR_WIDTH makrosu gerçekten bu dosyalarda tanımlanır, ancak bazı bilgiler altında gerçek bilgimi aşar.

Şimdiye kadar bulduğum koşullar:


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

ve :

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

Bu yüzden yardımına ihtiyacım var.

Not: Özellikle A.5.1'de açıklanan diğer tüm makrolarda aynı hatayı alıyorum: SCHAR_WIDTH, INT_WIDTH, LONG_WIDTH, vb.


Hangi tür koşullar?
LPs

1
@LP: Muhtemelen OP'nin anlamadığı bazı şeyler -> " gerçek bilgilerimi aşıyor. "
alk

2
Düzenlemeden sonra. __STDC_WANT_IEC_60559_BFP_EXT__komut satırı ile tanımlama veya
LPs

1
FWIW, POSIX'in CHAR_BIT8 olması gerekir, yani CHAR_WIDTHPOSIX sistemlerinde de 8 olmalıdır.
Andrew Henle

4
@pliski daha #defineönce yaptın mı #include?
LegendofPedro

Yanıtlar:


5

CHAR_WIDTHstandart değil, başka *_WIDTHmakrolar da değildir, ancak karakter türünün genişliği CHAR_BITzaten * ile aynı olmalıdır .

Genel olarak *_WIDTHmakrolara gelince , karşılık gelen imzasız türün maksimum değerinden derleme zamanı hesaplandıkları için kesinlikle gerekli değildir, yani, #define WIDTH_FROM_UNSIGNED_MAX(UnsignedMax)önişlemci koşullarında da kullanılabilen bir tamsayı sabit ifadesine genişleyen bir değere sahip olabilirsiniz ( #if), ancak uygulamalar biraz belirsiz olsa da (bkz . derleme zamanında bir tamsayı türünün genişliğini hesaplamanın herhangi bir yolu var mı? ), örneğin:

#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

Bazı insanlar sadece yaparlar CHAR_BIT * sizeof(integer_type), ancak bu kesinlikle taşınabilir değildir , çünkü integer_typedolgu bitlerine sahip olmadığını varsayar (genellikle teorik olarak bunlara sahip olmayabilir) ve #ifkoşullu olarak da kullanamaz .


* Ne yazık ki, bu bilgiyi toplamak için tüm standartlara atlamanız gerekiyor:

Bir tamsayı tipinin genişliği (hafif dolaylı olarak) dolgu içermeyen bit sayısı ( 6.2.6.2p6 ) olarak tanımlanır.

6.2.6.2p2signed char , herhangi bir dolgu biti olmadığını söylüyor . Tamsayıların C ( 6.2.6.2p2 ) ' de nasıl temsil edilebildiğinden , bu da unsigned charherhangi bir dolgu bitine sahip olamaz ve aynı değere sahipken veya ( 5.2.4.2.1p2 ) ile charaynı sınırlara sahip olması gerektiğinden ( yani 1, 6.5.3.4p4 ), bir ovada herhangi bir dolgu biti olamaz ve böylece == genişliği ( | | ) .signed charunsigned charsizeofcharCHAR_BIT charsigned charunsigned char

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.