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 C版本8.3.0,GMP版本6.1.2,MPFR版本4.0.2,MPC版本1.1.0编译的GNU C17(Ubuntu 8.3.0-6ubuntu1)版本8.3.0(x86_64-linux-gnu) ,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包含一个limits.h,其中包含来自同一目录的syslimits.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无法理解的一些->“ 超出了我的实际知识。
alk

2
编辑后。__STDC_WANT_IEC_60559_BFP_EXT__通过命令行定义或传递它
LP

1
FWIW,POSIX要求CHAR_BIT为8,这意味着CHAR_WIDTH在POSIX系统上也必须为8。
安德鲁·亨利

4
@pliski你#define在之前#include吗?
LegendofPedro

Answers:


5

CHAR_WIDTH不是标准的,也不是其他*_WIDTH任何宏,但是字符类型的宽度必须始终与CHAR_BIT* 相同。

*_WIDTH一般而言,对于宏,由于它们可以从相应的无符号类型的最大值进行编译时计算,因此并不一定要使用它们,也就是说,您可以将#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 charunsigned char5.2.4.2.1p2)相同的限制,同时具有相同的sizeof值(即1,6.5.3.4p4),一个平原char也不能有任何填充位,因此CHAR_BIT = =((char| signed char| unsigned char)的宽度

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.