当是uint8_t≠无符号的字符?(When is uint8_t ≠ unsigned char?

2019-08-31 17:53发布

据C和C ++, CHAR_BIT >= 8
但每当CHAR_BIT > 8uint8_t甚至不能被表示为8位。
它必须是大的,因为CHAR_BIT为系统上的任何数据类型的位的最小数目。

在一个什么样的系统,可uint8_t在法律上定义为比其他类型unsigned char

(如果答案是C和C ++不同的话,我想知道这两种)。

Answer 1:

如果它存在, uint8_t必须始终具有相同的宽度为unsigned char 。 但是,它不一定是同一类型; 它可以是一个独特的扩展整数类型。 它也不必具有相同的表示为unsigned char ; 例如,这些位可以以相反的顺序进行解释。 这是一个愚蠢的例子,但它更有意义的int8_t ,其中signed char可能是那些补充或同时签署幅度int8_t要求是二进制补码。

使用非炭扩展整数类型的一个另外的“优势” uint8_t即使在“正常”的系统是C的别名使用规则。 字符类型被允许别名任何东西,其防止从使用两个字符指针和指针到其它类型的重优化函数的编译器,除非restrict关键字已经施加良好。 然而,即使uint8_t具有完全相同的尺寸和代表性作为unsigned char ,如果实现做了它独特的,非字符类型,别名规则并不适用于它,编译器可以假设的对象类型uint8_tint ,例如,可从来没有别名。



Answer 2:

在一个什么样的系统,可uint8_t在法律上定义为比其他类型unsigned char

总之, uint8_t只能上合法系统定义,其中CHAR_BIT为8这是一个与正好是8值的比特和不填充比特的可寻址单元。

详细地说, CHAR_BIT限定的最小可寻址单元的宽度, uint8_t不能有填充比特; 当最小可寻址单元是正好宽8位,只能存在。 提供了CHAR_BIT为8, uint8_t可以通过用于不具有填充比特的任意8位无符号整数类型的类型的定义来限定。


下面介绍一下C11标准草案(n1570.pdf)说:

整数类型 1下面给出的值的大小5.2.4.2.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,无符号的字符,或符号的字符,(或合格的版本物)的结果为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种,这些类型是可选的。 然而,如果实现提供整数类型与具有2的补码表示的8宽度,16,32,或64位,无填充比特,以及(用于签名的类型),它应确定相应的typedef名称。

在“ 这些类型是可选的 ”重点是我的。 我希望这可以帮到你 :)



Answer 3:

没有人迄今已提到一种可能性:如果CHAR_BIT==8 ,不合格char是无符号的,它是在一定的ABI,那么uint8_t可能是一个typedef char ,而不是unsigned char 。 这一点很重要,至少,因为它影响着超负荷的选择(和它邪恶的双胞胎,名字改编),也就是说,如果你同时拥有foo(char)foo(unsigned char)的范围,呼吁foo与类型的参数uint8_t宁愿foo(char)这样的系统上。



文章来源: When is uint8_t ≠ unsigned char?