CHAR_WIDTHが宣言されていません


9

‘CHAR_WIDTH’ undeclared この単純なプログラムをコンパイルしようとすると、エラーが発生 します。

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

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

gcc ./show_char_width.c -o show_char_width

およびgcc:GNU C17(Ubuntu 8.3.0-6ubuntu1)バージョン8.3.0(x86_64-linux-gnu)、GNU Cバージョン8.3.0、GMPバージョン6.1.2、MPFRバージョン4.0.2、MPCバージョン1.1.0でコンパイル、islバージョンisl-0.20-GMP、カーネル:5.0.0-37-generic。

ここで述べたように、 CHAR_WIDTHはプログラムに含まれているlimits.hで定義する必要があります。では、なぜこのエラーが発生するのですか?

では-vオプション私は、ライブラリは、これらのディレクトリで検索されますことを見出しました。

#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を含むLimits.hが含まれています。これには、次のLimits.hが含まれています。 / usr / includeディレクトリ。

CHAR_WIDTHマクロは実際にこれらのファイルで定義されていますが、実際の知識を超える状況がいくつかあります。

私が今までに見つけた条件は次のとおりです。


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

と:

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

だからあなたの助けが必要です。

注:A.5.1で説明されている他のすべてのマクロ、特にSCHAR_WIDTH、INT_WIDTH、LONG_WIDTHなどで同じエラーが発生します。


どのような条件ですか?
LP

1
@LP:OPは理解していないことを、おそらくいくつかの- >「私の実際の知識を超えています。
アルク

2
編集後。__STDC_WANT_IEC_60559_BFP_EXT__コマンドラインで定義または渡す
LP

1
FWIW、POSIXはCHAR_BIT8である必要がCHAR_WIDTHあります。つまり、POSIXシステムでも8でなければなりません。
Andrew Henle

4
@pliskiはあなたの#define前に#include
LegendofPedro

回答:


5

CHAR_WIDTHは標準ではなく、他の*_WIDTHマクロでもありませんが、文字タイプの幅はCHAR_BITとにかく同じでなければなりません*。

用として*_WIDTH、彼らはコンパイル時計算可能対応するunsigned型の最大値から、つまり、あなたが持つことができていると一般的にマクロ、彼らは厳密に必要とされていない#define WIDTH_FROM_UNSIGNED_MAX(UnsignedMax)ことプリプロセッサの条件でも使用可能だ整数定数式に展開(#if)、ただし、実装は少しあいまいです(コンパイル時に整数型の幅を計算する方法はありますか?)、例えば:

#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

一部の人はそうするだけですがCHAR_BIT * sizeof(integer_type)、厳密には移植可能ではありinteger_typeません。なぜなら、埋め込みビットがないことを想定しているため(通常はありませんが、理論的には埋め込みビットがある可能性があります)、#if条件付きでも使用できません。


*残念ながら、この情報を収集するには、標準全体をジャンプする必要があります。

整数型の幅は、(わずかに間接的に)非パディングビットの数(6.2.6.2p6)として定義されます。

6.2.6.2p2signed charパディングビットがないと言います。Cで整数を表現する方法(6.2.6.2p2)のため、unsigned charパディングビットもないことを意味します。また、同じ値()charと同じ制限(signed charまたは5.2.4.2.1p2)を持つ必要があるため、つまり、1、6.5.3.4p4)、プレーンにはパディングビットを含めることはできないため、== width of(| | )になります。unsigned charsizeofcharCHAR_BIT charsigned charunsigned char

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.