根据C和C ++,CHAR_BIT >= 8
但是,只要CHAR_BIT > 8
,uint8_t
甚至无法表示为8位
它必须更大,因为CHAR_BIT
是系统上任何数据类型的最小位数。
在uint8_t
以外的哪种类型的系统可以合法地定义为unsigned char
以外的类型?
(如果C和C ++的答案不同,那么我想知道两者。)
答案 0 :(得分:56)
如果存在,uint8_t
必须始终与unsigned char
具有相同的宽度。但是,它不一定是同一类型;它可能是一个独特的扩展整数类型。它也不必具有与unsigned char
相同的表示形式;例如,可以以相反的顺序解释比特。这是一个愚蠢的例子,但对int8_t
更有意义,其中signed char
可能是补码或符号幅度,而int8_t
则需要补码。
即使在“普通”系统上,对uint8_t
使用非char扩展整数类型的另一个“好处”是C的别名规则。允许字符类型别名,这可以防止编译器大量优化使用字符指针和指向其他类型的指针的函数,除非restrict
关键字已被很好地应用。但是,即使uint8_t
具有与unsigned char
完全相同的大小和表示,如果实现使其成为不同的非字符类型,则别名规则将不适用于它,并且编译器可以假设例如,uint8_t
和int
类型的对象永远不会别名。
答案 1 :(得分:30)
哪种系统
uint8_t
可以合法地定义为unsigned char
以外的类型?
总之,uint8_t
只能在CHAR_BIT
为8的系统上合法定义。它是一个可寻址单元,正好有8个值位且没有填充位。
详细地说,CHAR_BIT
定义了最小可寻址单元的宽度,uint8_t
不能有填充位;它只能在最小可寻址单元正好为8位宽时存在。提供CHAR_BIT
为8,uint8_t
可以由任何没有填充位的8位无符号整数类型的类型定义定义。
以下是C11标准草案(n1570.pdf)所说的内容:
5.2.4.2.1整数类型的大小 1下面给出的值应替换为适用于#if的常量表达式 预处理指令。 ......他们的实施定义值应相等或 所示的数字(绝对值)大于相同的符号。
-- number of bits for smallest object that is not a bit-field (byte) CHAR_BIT 8
因此,最小的对象必须包含正好的CHAR_BIT位。
6.5.3.4 sizeof和_Alignof运算符
...
4当sizeof应用于类型为char,unsigned的操作数时 char,或signed char,(或其合格版本)的结果是 1. ...
因此,那些是(一些)最小的可寻址单元。显然int8_t
和uint8_t
也可以被认为是最小的可寻址单位,只要它们存在。
7.20.1.1精确宽度整数类型
1 typedef名称intN_t指定带宽度的有符号整数类型 N,没有填充位,以及二进制补码表示。从而, int8_t表示这样的有符号整数类型,其宽度恰好为8 位。
2 typedef名称uintN_t指定带有的无符号整数类型 宽度N和无填充位。因此,uint24_t表示这样的无符号 整数类型,宽度恰好为24位。
3 这些类型是可选的。但是,如果实现提供 宽度为8,16,32或64位的整数类型,无填充位, 和(对于签名类型)有两个补码 表示,它应定义相应的typedef名称。
强调“这些类型是可选的”是我的。我希望这有用:)
答案 2 :(得分:6)
迄今为止没有人提到的可能性:如果CHAR_BIT==8
和非限定char
是无符号的,它在某些ABI中,那么uint8_t
可能是{{1}的typedef而不是char
。这至少在影响过载选择(及其邪恶的双胞胎,名称修改)的情况下是重要的,即如果你在范围内同时拥有unsigned char
和foo(char)
,则用参数调用foo(unsigned char)
类型foo
在这样的系统上更喜欢uint8_t
。