什么时候uint8_t≠unsigned char?

时间:2013-04-22 01:45:42

标签: c++ c types unsigned-char uint8t

根据C和C ++,CHAR_BIT >= 8 但是,只要CHAR_BIT > 8uint8_t甚至无法表示为8位 它必须更大,因为CHAR_BIT是系统上任何数据类型的最小位数。

uint8_t以外的哪种类型的系统可以合法地定义为unsigned char以外的类型?

(如果C和C ++的答案不同,那么我想知道两者。)

3 个答案:

答案 0 :(得分:56)

如果存在,uint8_t必须始终与unsigned char具有相同的宽度。但是,它不一定是同一类型;它可能是一个独特的扩展整数类型。它也不必具有与unsigned char相同的表示形式;例如,可以以相反的顺序解释比特。这是一个愚蠢的例子,但对int8_t更有意义,其中signed char可能是补码或符号幅度,而int8_t则需要补码。

即使在“普通”系统上,对uint8_t使用非char扩展整数类型的另一个“好处”是C的别名规则。允许字符类型别名,这可以防止编译器大量优化使用字符指针和指向其他类型的指针的函数,除非restrict关键字已被很好地应用。但是,即使uint8_t具有与unsigned char完全相同的大小和表示,如果实现使其成为不同的非字符类型,则别名规则将不适用于它,并且编译器可以假设例如,uint8_tint类型的对象永远不会别名。

答案 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_tuint8_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 charfoo(char),则用参数调用foo(unsigned char)类型foo在这样的系统上更喜欢uint8_t