如何可靠检查C++数据类型的字节大小及最值限制?
C++跨架构数据类型准确性检查方案优化
由于C++数据类型的大小和限制会随架构变化,我希望确保自定义类型的准确性。我基于stdint.h定义了自定义typedef类型,最初用运行时if判断检查类型的字节大小和最值,但担心无法适配所有系统。后来改用static_assert做编译时检查,但对size_t在未知架构下的检查存在疑问,想找更优的检查方案。
自定义类型定义代码
#include <stdint.h> // 更精确的大小typedef定义 typedef int8_t int8; #define int8_min INT8_MIN #define int8_max INT8_MAX typedef uint8_t uint8; #define uint8_min 0 #define uint8_max UINT8_MAX typedef int16_t int16; #define int16_min INT16_MIN #define int16_max INT16_MAX typedef uint16_t uint16; #define uint16_min 0 #define uint16_max UINT16_MAX typedef int32_t int32; #define int32_min INT32_MIN #define int32_max INT32_MAX typedef uint32_t uint32; #define uint32_min 0 #define uint32_max UINT32_MAX typedef int64_t int64; #define int64_min INT64_MIN #define int64_max INT64_MAX typedef uint64_t uint64; #define uint64_min 0 #define uint64_max UINT64_MAX // typedef size_t size; #define size_min 0 #define size_max SIZE_MAX
原运行时检查代码
if (!(sizeof(int8) == 1 && int8_min == -128 && int8_max == 127)) // 报错处理 if (!(sizeof(uint8) == 1 && uint8_max == 255)) // 报错处理 if (!(sizeof(int16) == 2 && int16_min == -32768 && int16_max == 32767)) // 报错处理 if (!(sizeof(uint16) == 2 && uint16_max == 65535)) // 报错处理 if (!(sizeof(int32) == 4 && int32_min == -2147483648 && int32_max == 2147483647)) // 报错处理 if (!(sizeof(uint32) == 4 && uint32_max == 4294967295)) // 报错处理 if (!(sizeof(int64) == 8 && int64_min == (-9223372036854775807 - 1) && int64_max == 9223372036854775807)) // 报错处理 if (!(sizeof(uint64) == 8 && uint64_max == 18446744073709551615)) // 报错处理 #ifdef X64 if (!(sizeof(size_t) == 8 && size_max == 18446744073709551615)) // 报错处理 #elif defined(X32) if (!(sizeof(size_t) == 4 && size_max == 4294967295)) // 报错处理 #else // 暂时没考虑这部分 #endif // X64
修改后的编译时检查代码
static_assert(sizeof(int8) == 1 && int8_min == -128 && int8_max == 127); static_assert(sizeof(uint8) == 1 && uint8_max == 255); static_assert(sizeof(int16) == 2 && int16_min == -32768 && int16_max == 32767); static_assert(sizeof(uint16) == 2 && uint16_max == 65535); static_assert(sizeof(int32) == 4 && int32_min == -2147483648 && int32_max == 2147483647); static_assert(sizeof(uint32) == 4 && uint32_max == 4294967295); static_assert(sizeof(int64) == 8 && int64_min == (-9223372036854775807 - 1) && int64_max == 9223372036854775807); static_assert(sizeof(uint64) == 8 && uint64_max == 18446744073709551615); #ifdef X64 static_assert(sizeof(size_t) == 8 && size_max == 18446744073709551615); #elif defined(X32) static_assert(sizeof(size_t) == 4 && size_max == 4294967295); #else static_assert(???); #endif // X64
优化方案
1. 简化标准类型的检查
你基于stdint.h定义的int8/uint8等类型,stdint.h已经强制保证这些类型的大小和最值符合标准(比如int8_t一定是1字节、范围-128到127),所以针对这些类型的static_assert完全是冗余的,可以直接删除,直接依赖标准库的保证即可。
2. size_t的编译时检查优化
不需要依赖X64/X32这类自定义宏,直接通过匹配标准无符号整数类型来做通用检查:
// 确保size_t是标准32位或64位无符号整数 static_assert( (sizeof(size_t) == sizeof(uint32_t) && size_max == UINT32_MAX) || (sizeof(size_t) == sizeof(uint64_t) && size_max == UINT64_MAX), "size_t must be either 32-bit or 64-bit unsigned integer" );
这个断言不依赖架构宏,只要size_t是常见的32位或64位无符号类型就能通过检查,覆盖绝大多数主流架构场景。如果需要支持更罕见的架构,再根据需求扩展判断条件即可。
3. 自定义size类型的规范
如果要给size_t定义自定义别名,直接写:
typedef size_t size;
同时保留size_min和size_max的定义即可,上面的断言同样适用。
内容的提问来源于stack exchange,提问作者Ibrahim Ozdemir
相关产品推荐
相关产品推荐

