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 ควรกำหนดเป็นขีด จำกัด ซึ่งรวมอยู่ในโปรแกรมของฉัน เหตุใดฉันจึงได้รับข้อผิดพลาดนี้

ด้วย-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 จาก dir เดียวกันซึ่งจะรวมถึงขีด จำกัด ถัดไปซึ่งจากความเข้าใจของฉันควรอยู่ใน ไดเร็กทอรี / 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 เป็นต้น


เงื่อนไขชนิดใด
LPs

1
@LP: อาจเป็นไปได้ว่า OP ไม่เข้าใจ -> " เกินกว่าความรู้จริงของฉัน "
alk

2
หลังจากแก้ไขแล้ว กำหนด__STDC_WANT_IEC_60559_BFP_EXT__หรือส่งผ่านบรรทัดคำสั่ง
LP

1
FWIW, POSIX ต้องCHAR_BITเป็น 8 ซึ่งควรหมายถึงCHAR_WIDTHต้องเป็น 8 ในระบบ POSIX
Andrew Henle

4
@pliski คุณทำ#defineมาก่อน#includeหรือไม่
LegendofPedro

คำตอบ:


5

CHAR_WIDTHไม่ใช่มาตรฐานหรือ*_WIDTHมาโครอื่น ๆแต่ความกว้างของประเภทอักขระจะต้องเหมือนกันCHAR_BITอย่างไรก็ตาม

สำหรับ*_WIDTHแมโครโดยทั่วไปแล้วพวกเขาไม่ต้องการอย่างเข้มงวดเนื่องจากพวกเขาจะรวบรวมเวลาคำนวณจากมูลค่าสูงสุดของประเภทที่ไม่ได้ลงนามที่สอดคล้องกันคือคุณสามารถมีการ#define WIDTH_FROM_UNSIGNED_MAX(UnsignedMax)ขยายตัวที่การแสดงออกคงที่จำนวนเต็มที่ใช้งานได้ในเงื่อนไข preprocessor ( #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.2p2บอกว่าsigned charไม่มี padding บิตใด ๆ เนื่องจากวิธีที่จำนวนเต็มสามารถแสดงใน C ( 6.2.6.2p2 ) ซึ่งหมายความว่าunsigned charไม่สามารถมีบิต padding ใด ๆ และเนื่องจากcharต้องมีข้อ จำกัด เช่นเดียวกับsigned charหรือunsigned char( 5.2.4.2.1p2 ) ในขณะที่มีsizeofค่าเดียวกัน( ได้แก่ 1, 6.5.3.4p4 ) ธรรมดาcharไม่สามารถมีบิต padding ใดใดและเพื่อให้CHAR_BIT == ความกว้างของ ( char| signed char|unsigned char )

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.