Created
June 12, 2024 12:00
-
-
Save ian-abbott/ec46b37bb759f8b3e1e43a4bdec556ff to your computer and use it in GitHub Desktop.
Show widths of standard integer types when C23 x_WIDTH macros not available
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <limits.h> | |
#include <stdint.h> | |
/* Number of bits in inttype_MAX, or in any (1<<k)-1 where 0 <= k < 2040 */ | |
/* (Attributed to Hallvard B. Furuseth.) */ | |
#define IMAX_BITS(m) ((m)/((m)%255+1) / 255%255*8 + 7-86/((m)%255+12)) | |
/* Helper macros. */ | |
#define MY___WIDTH(x) IMAX_BITS(x##_MAX) | |
#define MY__U__WIDTH(x) MY___WIDTH(U##x) | |
/* | |
* Note: the type of the MY_xxx_WIDTH constants defined below | |
* might not be `int`, so be careful when using them where default argument | |
* promotions are in effect because they may need an explicit type conversion | |
* (type cast). However, they do have the advantage of being usable in | |
* constant expressions for preprocessor `#if` and `#elif` directives. | |
*/ | |
#define MY_BOOL_WIDTH 1 | |
#define MY_SHRT_WIDTH MY__U__WIDTH(SHRT) | |
#define MY_USHRT_WIDTH MY__U__WIDTH(SHRT) | |
#define MY_INT_WIDTH MY__U__WIDTH(INT) | |
#define MY_UINT_WIDTH MY__U__WIDTH(INT) | |
#define MY_LONG_WIDTH MY__U__WIDTH(LONG) | |
#define MY_ULONG_WIDTH MY__U__WIDTH(LONG) | |
#define MY_LLONG_WIDTH MY__U__WIDTH(LLONG) | |
#define MY_ULLONG_WIDTH MY__U__WIDTH(LLONG) | |
#ifdef INT8_MAX | |
#define MY_INT8_WIDTH 8 | |
#define MY_UINT8_WIDTH 8 | |
#endif | |
#ifdef INT16_MAX | |
#define MY_INT16_WIDTH 16 | |
#define MY_UINT16_WIDTH 16 | |
#endif | |
#ifdef INT32_MAX | |
#define MY_INT32_WIDTH 32 | |
#define MY_UINT32_WIDTH 32 | |
#endif | |
#ifdef INT64_MAX | |
#define MY_INT64_WIDTH 64 | |
#define MY_UINT64_WIDTH 64 | |
#endif | |
#define MY_INT_LEAST8_WIDTH MY__U__WIDTH(INT_LEAST8) | |
#define MY_UINT_LEAST8_WIDTH MY__U__WIDTH(INT_LEAST8) | |
#define MY_INT_LEAST16_WIDTH MY__U__WIDTH(INT_LEAST16) | |
#define MY_UINT_LEAST16_WIDTH MY__U__WIDTH(INT_LEAST16) | |
#define MY_INT_LEAST32_WIDTH MY__U__WIDTH(INT_LEAST32) | |
#define MY_UINT_LEAST32_WIDTH MY__U__WIDTH(INT_LEAST32) | |
#define MY_INT_LEAST64_WIDTH MY__U__WIDTH(INT_LEAST64) | |
#define MY_UINT_LEAST64_WIDTH MY__U__WIDTH(INT_LEAST64) | |
#define MY_INT_FAST8_WIDTH MY__U__WIDTH(INT_FAST8) | |
#define MY_UINT_FAST8_WIDTH MY__U__WIDTH(INT_FAST8) | |
#define MY_INT_FAST16_WIDTH MY__U__WIDTH(INT_FAST16) | |
#define MY_UINT_FAST16_WIDTH MY__U__WIDTH(INT_FAST16) | |
#define MY_INT_FAST32_WIDTH MY__U__WIDTH(INT_FAST32) | |
#define MY_UINT_FAST32_WIDTH MY__U__WIDTH(INT_FAST32) | |
#define MY_INT_FAST64_WIDTH MY__U__WIDTH(INT_FAST64) | |
#define MY_UINT_FAST64_WIDTH MY__U__WIDTH(INT_FAST64) | |
#define MY_INTPTR_WIDTH MY__U__WIDTH(INTPTR) | |
#define MY_UINTPTR_WIDTH MY__U__WIDTH(INTPTR) | |
#define MY_INTMAX_WIDTH MY__U__WIDTH(INTMAX) | |
#define MY_UINTMAX_WIDTH MY__U__WIDTH(INTMAX) | |
#define MY_PTRDIFF_WIDTH (MY___WIDTH(PTRDIFF) + 1) | |
#if SIG_ATOMIC_MIN | |
#define MY_SIG_ATOMIC_WIDTH (MY___WIDTH(SIG_ATOMIC) + 1) | |
#else | |
#define MY_SIG_ATOMIC_WIDTH MY___WIDTH(SIG_ATOMIC) | |
#endif | |
#define MY_SIZE_WIDTH MY___WIDTH(SIZE) | |
#if WCHAR_MIN | |
#define MY_WCHAR_WIDTH (MY___WIDTH(WCHAR) + 1) | |
#else | |
#define MY_WCHAR_WIDTH MY___WIDTH(WCHAR) | |
#endif | |
#if WINT_MIN | |
#define MY_WINT_WIDTH (MY___WIDTH(WINT) + 1) | |
#else | |
#define MY_WINT_WIDTH MY___WIDTH(WINT) | |
#endif | |
#include <stdio.h> | |
#define PRINT(name) printf("%s = %d\n", #name, (int)name); | |
int main(void) | |
{ | |
PRINT(MY_BOOL_WIDTH); | |
PRINT(MY_SHRT_WIDTH); | |
PRINT(MY_USHRT_WIDTH); | |
PRINT(MY_INT_WIDTH); | |
PRINT(MY_UINT_WIDTH); | |
PRINT(MY_LONG_WIDTH); | |
PRINT(MY_ULONG_WIDTH); | |
PRINT(MY_LLONG_WIDTH); | |
PRINT(MY_ULLONG_WIDTH); | |
#ifdef INT8_MAX | |
PRINT(MY_INT8_WIDTH); | |
PRINT(MY_UINT8_WIDTH); | |
#endif | |
#ifdef INT16_MAX | |
PRINT(MY_INT16_WIDTH); | |
PRINT(MY_UINT16_WIDTH); | |
#endif | |
#ifdef INT32_MAX | |
PRINT(MY_INT32_WIDTH); | |
PRINT(MY_UINT32_WIDTH); | |
#endif | |
#ifdef INT64_MAX | |
PRINT(MY_INT64_WIDTH); | |
PRINT(MY_UINT64_WIDTH); | |
#endif | |
PRINT(MY_INT_LEAST8_WIDTH); | |
PRINT(MY_UINT_LEAST8_WIDTH); | |
PRINT(MY_INT_LEAST16_WIDTH); | |
PRINT(MY_UINT_LEAST16_WIDTH); | |
PRINT(MY_INT_LEAST32_WIDTH); | |
PRINT(MY_UINT_LEAST32_WIDTH); | |
PRINT(MY_INT_LEAST64_WIDTH); | |
PRINT(MY_UINT_LEAST64_WIDTH); | |
PRINT(MY_INT_FAST8_WIDTH); | |
PRINT(MY_UINT_FAST8_WIDTH); | |
PRINT(MY_INT_FAST16_WIDTH); | |
PRINT(MY_UINT_FAST16_WIDTH); | |
PRINT(MY_INT_FAST32_WIDTH); | |
PRINT(MY_UINT_FAST32_WIDTH); | |
PRINT(MY_INT_FAST64_WIDTH); | |
PRINT(MY_UINT_FAST64_WIDTH); | |
PRINT(MY_INTPTR_WIDTH); | |
PRINT(MY_UINTPTR_WIDTH); | |
PRINT(MY_INTMAX_WIDTH); | |
PRINT(MY_UINTMAX_WIDTH); | |
PRINT(MY_PTRDIFF_WIDTH); | |
PRINT(MY_SIG_ATOMIC_WIDTH); | |
PRINT(MY_SIZE_WIDTH); | |
PRINT(MY_WCHAR_WIDTH); | |
PRINT(MY_WINT_WIDTH); | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment