【发布时间】:2023-04-11 03:28:01
【问题描述】:
我正在编写一个需要具有确定大小的无符号类型的程序。我需要一个 uint8、uint16、uint32 和 uint64,并且我需要在 types.h 中定义它们,这样无论平台如何,它们都将始终正确定义。
我的问题是,如何使用预处理器宏检查每个平台上不同类型的大小,以便在 types.h 标头中正确定义自定义类型?
【问题讨论】:
标签: c types macros size c-preprocessor
我正在编写一个需要具有确定大小的无符号类型的程序。我需要一个 uint8、uint16、uint32 和 uint64,并且我需要在 types.h 中定义它们,这样无论平台如何,它们都将始终正确定义。
我的问题是,如何使用预处理器宏检查每个平台上不同类型的大小,以便在 types.h 标头中正确定义自定义类型?
【问题讨论】:
标签: c types macros size c-preprocessor
312 #define SDL_COMPILE_TIME_ASSERT(name, x) \
313 typedef int SDL_compile_time_assert_ ## name[(x) * 2 - 1]
316 SDL_COMPILE_TIME_ASSERT(uint8, sizeof(Uint8) == 1);
317 SDL_COMPILE_TIME_ASSERT(sint8, sizeof(Sint8) == 1);
318 SDL_COMPILE_TIME_ASSERT(uint16, sizeof(Uint16) == 2);
319 SDL_COMPILE_TIME_ASSERT(sint16, sizeof(Sint16) == 2);
320 SDL_COMPILE_TIME_ASSERT(uint32, sizeof(Uint32) == 4);
321 SDL_COMPILE_TIME_ASSERT(sint32, sizeof(Sint32) == 4);
322 SDL_COMPILE_TIME_ASSERT(uint64, sizeof(Uint64) == 8);
323 SDL_COMPILE_TIME_ASSERT(sint64, sizeof(Sint64) == 8);
Checkout SDL https://hg.libsdl.org/SDL/file/d470fa5477b7/include/SDL_stdinc.h#l316 他们在编译时静态断言大小。就像@Mehrdad 说的,如果你的目标没有 64 位整数,它就不能独立于平台。
【讨论】:
C 对这些有标准的typedefs。不要定义你自己的。它们被称为intN_t 和uintN_t,其中N 是8、16、32、64 等。包括<stdint.h> 以获取它们。
如果您使用的是缺少stdint.h 的古老编译器,您可以简单地为您正在使用的任何损坏的平台提供适当的typedef。我敢打赌,在没有stdint.h 的情况下遇到的任何非嵌入式目标:
CHAR_BIT 是 8。sizeof(char) 是 1。
sizeof(short) 是 2。sizeof(int) 是 4。sizeof(long long),如果类型存在,则为8。因此,只需将它们用作损坏系统的填充物。
【讨论】:
inttypes.h 也很容易与这些类型一起使用。这些头文件肯定在 POSIX 中,但我不知道它们也在 C 标准中。整洁。
#if UINT_MAX != 0xFFFFFFFF#error "int is not 32-bit"#endif
您甚至无法保证所有这些类型都存在在您的平台上(比如说,甚至可能没有 64 位整数),所以您可以'不可能编写独立于平台的代码来在编译时检测它们。
【讨论】:
sizeof(long long int) >= sizeof(long int) >= sizeof(short int)... 但是出于所有实际目的,它们都可以是 16 位的!所以你必须先假设一些非标准的东西才能写出这样的代码。
ULONG_MAX 至少为 2^32-1,ULLONG_MAX 至少为 2^64-1。