CHAR_WIDTH không được khai báo


9

Tôi gặp lỗi ‘CHAR_WIDTH’ undeclared khi tôi cố gắng biên dịch chương trình đơn giản này:

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

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

với

gcc ./show_char_width.c -o show_char_width

và gcc: GNU C17 (Ubuntu 8.3.0-6ubfox1) phiên bản 8.3.0 (x86_64-linux-gnu) được biên dịch bởi GNU C phiên bản 8.3.0, phiên bản GMP 6.1.2, phiên bản MPFR 4.0.2, MPC phiên bản 1.1.0 , phiên bản isl isl-0.20-GMP, kernel: 5.0.0-37-generic.

Như đã nêu ở đây CHAR_WIDTH nên được xác định trong giới hạn.h được bao gồm trong chương trình của tôi. Vậy tại sao tôi nhận được lỗi này?

Với -vtùy chọn tôi thấy rằng thư viện sẽ được tìm kiếm trong các thư mục đó:

#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 chứa một giới hạn.h bao gồm syslimits.h từ cùng một thư mục bao gồm các giới hạn tiếp theo.h, theo cách hiểu của tôi nên được đặt trong thư mục / usr / bao gồm.

Macro CHAR_WIDTH thực sự được xác định trong các tệp đó nhưng trong một số điều kiện vượt quá kiến ​​thức thực tế của tôi.

Các điều kiện tôi tìm thấy cho đến bây giờ là:


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

và:

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

Đó là lý do tại sao tôi cần sự giúp đỡ của bạn.

Lưu ý: Tôi nhận được cùng một lỗi với tất cả các macro khác được mô tả trong A.5.1: SCHAR_WIDTH, INT_WIDTH, LONG_WIDTH, v.v.


Những loại điều kiện?
LP

1
@LP: có thể một số điều mà OP không hiểu -> " vượt quá kiến ​​thức thực tế của tôi. "
kiềm

2
Sau khi chỉnh sửa. xác định __STDC_WANT_IEC_60559_BFP_EXT__hoặc vượt qua nó bằng dòng lệnh
LP

1
FWIW, POSIX yêu cầu CHAR_BITphải là 8, nghĩa là CHAR_WIDTHcũng phải là 8 trên các hệ thống POSIX.
Andrew Henle

4
@pliski bạn đã làm #definetrước #include?
LegendofPedro

Câu trả lời:


5

CHAR_WIDTHkhông phải là tiêu chuẩn, cũng không phải là bất kỳ *_WIDTHmacro nào khác , nhưng độ rộng của một loại ký tự phải giống như CHAR_BITdù sao *.

Đối với các *_WIDTHmacro nói chung, chúng không thực sự cần thiết vì chúng có thể tính toán được theo thời gian từ giá trị tối đa của loại không dấu tương ứng, nghĩa là bạn có thể #define WIDTH_FROM_UNSIGNED_MAX(UnsignedMax)mở rộng thành biểu thức hằng số nguyên có thể sử dụng được trong các điều kiện tiền xử lý ( #if), mặc dù việc triển khai hơi khó hiểu một chút (xem Có cách nào để tính độ rộng của một kiểu số nguyên tại thời gian biên dịch không? ), ví dụ:

#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

Một số người chỉ làm CHAR_BIT * sizeof(integer_type), nhưng điều đó không hoàn toàn di động , vì nó giả sử integer_typekhông có bit đệm (thường thì không nhưng về mặt lý thuyết nó có thể có chúng) và cũng không thể sử dụng nó trong các #ifđiều kiện.


* Thật không may, để lượm lặt thông tin này, bạn cần phải nhảy qua tiêu chuẩn:

Độ rộng của một kiểu số nguyên là (hơi gián tiếp) được định nghĩa là số bit không đệm của nó ( 6.2.6.2p6 ).

6.2.6.2p2 nói rằng signed charkhông có bất kỳ bit đệm nào. Do cách các số nguyên có thể được biểu diễn trong C ( 6.2.6.2p2 ), điều đó ngụ ý rằng unsigned charkhông thể có bất kỳ bit đệm nào, và vì charphải có cùng giới hạn với signed charhoặc unsigned char( 5.2.4.2.1p2 ) trong khi có cùng sizeofgiá trị ( cụ thể là 1, 6.5.3.4p4 ), một đồng bằng charkhông thể có bất kỳ bit đệm nào, và vì vậy CHAR_BIT == width của ( char| signed char| unsigned char) .

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.