无符号整数类型总是大小不同吗?
Are unsigned integer types always of different sizes?
是否有可能(符合 C 规范)有 2 个不同 范围 但具有相同 大小 的无符号整数类型(由于填充)?
#include <inttypes.h>
#include <stdio.h>
#include <stdint.h>
int main(void) {
printf("Size:%zu Max:%llu\n",
sizeof(unsigned_32_t), (unsigned long long) ((unsigned_32_t) -1));
// Size:4 Max:4294967295
printf("Size:%zu Max:%llu\n",
sizeof(unsigned_24_t), (unsigned long long) ((unsigned_24_t) -1));
// Size:4 Max:16777215
return 0;
不使用精确宽度整数类型,不能有填充。
当然这并不常见 - 只是想知道规范允许什么。
总的来说,是的,这是绝对有可能的。
对于 <stdint.h>
中定义的 uintN_t
类型的特定情况,如您所述 (C11 §7.20.1.1):
The typedef name uintN_t designates an unsigned integer type with width N
and no padding bits. Thus, uint24_t denotes such an unsigned integer
type with a width of exactly 24 bits.
具有 36 位内存总线和 9 位 char
的系统完全有可能作为兼容性帮助包括 8 位、16 位和 32 位无符号类型(*) 分别包装 mod 256、65536 和 4294967296。这些类型将使用与 9、18 和 36 位类型相同的存储量,并且将以基本相同的方式存储,只是操作会屏蔽掉高位。给定一个 16 位无符号变量 u
,编译器可以实现 u++
等效于 u=(u+1) & 65535;
并将 u>23
实现为 18 位比较,或者可以实现 u++
作为 18 位增量并将 u>23
实现为 (u & 65535)>23
.
(*) 标准规定,如果 uint8_t
、uint16_t
和 uint32_t
都已定义,则必须使用 8、16 或 32 位存储 并且没有填充位,因此如果 36 位机器的符合标准的编译器定义了这种大小为 2 的幂的类型,则它必须使用其他名称;不幸的是,该标准为在数字上表现正确但不满足预期存储布局的类型提供了标准名称。
是否有可能(符合 C 规范)有 2 个不同 范围 但具有相同 大小 的无符号整数类型(由于填充)?
#include <inttypes.h>
#include <stdio.h>
#include <stdint.h>
int main(void) {
printf("Size:%zu Max:%llu\n",
sizeof(unsigned_32_t), (unsigned long long) ((unsigned_32_t) -1));
// Size:4 Max:4294967295
printf("Size:%zu Max:%llu\n",
sizeof(unsigned_24_t), (unsigned long long) ((unsigned_24_t) -1));
// Size:4 Max:16777215
return 0;
不使用精确宽度整数类型,不能有填充。
当然这并不常见 - 只是想知道规范允许什么。
总的来说,是的,这是绝对有可能的。
对于 <stdint.h>
中定义的 uintN_t
类型的特定情况,如您所述 (C11 §7.20.1.1):
The typedef name uintN_t designates an unsigned integer type with width N and no padding bits. Thus, uint24_t denotes such an unsigned integer type with a width of exactly 24 bits.
具有 36 位内存总线和 9 位 char
的系统完全有可能作为兼容性帮助包括 8 位、16 位和 32 位无符号类型(*) 分别包装 mod 256、65536 和 4294967296。这些类型将使用与 9、18 和 36 位类型相同的存储量,并且将以基本相同的方式存储,只是操作会屏蔽掉高位。给定一个 16 位无符号变量 u
,编译器可以实现 u++
等效于 u=(u+1) & 65535;
并将 u>23
实现为 18 位比较,或者可以实现 u++
作为 18 位增量并将 u>23
实现为 (u & 65535)>23
.
(*) 标准规定,如果 uint8_t
、uint16_t
和 uint32_t
都已定义,则必须使用 8、16 或 32 位存储 并且没有填充位,因此如果 36 位机器的符合标准的编译器定义了这种大小为 2 的幂的类型,则它必须使用其他名称;不幸的是,该标准为在数字上表现正确但不满足预期存储布局的类型提供了标准名称。