如何用_Generic检测任意N的_BitInt(N)与unsigned _BitInt(N)类型
C23中无需枚举所有N即可检测任意_BitInt(N)/unsigned _BitInt(N)类型吗?
问题背景
根据ISO/IEC 9899:2024(C23标准)6.2.5类型章节规定,_BitInt(N)是带符号位精确整数类型,不同N值对应独立的类型。用户尝试用_Generic宏编写类型检测代码,但单独使用_BitInt(不指定N)无法编译,仅指定具体N的_BitInt(N)能正常运行,因此询问是否无需枚举2到BITINT_MAXWIDTH的所有N,即可判断表达式是否为任意N的_BitInt(N)或unsigned _BitInt(N)类型。
结论与方案
标准C23层面的限制
标准C23没有提供直接匹配任意_BitInt(N)/unsigned _BitInt(N)的_Generic分支语法。因为每个不同N值的_BitInt类型都是独立的不同类型,_Generic仅支持匹配具体类型或兼容类型,没有通配符式的类型匹配机制。如果完全依赖标准语法,确实需要枚举所有可能的N值才能覆盖所有_BitInt类型。
利用编译器扩展的可行方案
主流编译器(如GCC、Clang)提供了内置函数可间接实现该需求,无需枚举所有N:
- 使用
__builtin_types_compatible_p判断类型兼容性 - 结合C23标准内置宏
__BITINT_WIDTH__获取_BitInt类型的宽度N
示例代码如下:
#include <stdint.h> // 判断表达式是否为任意_BitInt(N)或unsigned _BitInt(N)类型 #define IS_BITINT(expr) \ _Generic((expr), \ default: 0, \ intmax_t: __builtin_types_compatible_p(__typeof__(expr), _BitInt(__BITINT_WIDTH__(expr))) || \ __builtin_types_compatible_p(__typeof__(expr), unsigned _BitInt(__BITINT_WIDTH__(expr))), \ uintmax_t: __builtin_types_compatible_p(__typeof__(expr), _BitInt(__BITINT_WIDTH__(expr))) || \ __builtin_types_compatible_p(__typeof__(expr), unsigned _BitInt(__BITINT_WIDTH__(expr))) \ )
代码说明
_Generic的default分支处理非整数类型或非_BitInt的整数类型,直接返回0intmax_t/uintmax_t分支覆盖_BitInt类型提升后的情况,通过__typeof__(expr)获取表达式的实际类型,再用__builtin_types_compatible_p判断该类型是否为对应宽度的_BitInt(N)或unsigned _BitInt(N)__BITINT_WIDTH__是C23标准宏,仅对_BitInt类型有效,返回其宽度N;对非_BitInt类型的行为由编译器定义,但在_Generic的对应分支中只会处理_BitInt提升后的类型,因此不会触发未定义行为
内容的提问来源于stack exchange,提问作者Madagascar
相关产品推荐
相关产品推荐

