uint8_t可以是非字符类型吗?

在这个答案和附带的评论中, Pavel Minaev提出以下论点:在C中, uint8_t可以被typedef的唯一类型是charunsigned char 。 我正在看这个 C标准草案 。

  • uint8_t的存在意味着存在相应的类型int8_t (7.18.1p1)。
  • int8_t是8位宽,没有填充位(7.18.1.1p1)。
  • 相应的类型具有相同的宽度(6.2.5p6),因此uint8_t也是8位宽。
  • unsigned charCHAR_BIT位宽(5.2.4.2.1p2和6.2.6.1p3)。
  • CHAR_BIT至少为8(5.2.4.2.1p1)。
  • CHAR_BIT最多为8,因为uint8_tunsigned char ,或者是非unsigned char ,非位字段类型,其宽度是CHAR_BIT (6.2.6.1p4)的倍数。

根据这个论点,我同意,如果uint8_t存在,那么它和unsigned char都有相同的表示:8个值位和0个填充位。 这似乎并不强迫它们属于同一类型(例如,6.2.5p14)。

是否允许uint8_t被类型定义为扩展无符号整数类型(6.2.5p6),其表示forms与unsigned char相同? 当然它必须是typedef’d(7.18.1.1p2),并且它不能是除unsigned char之外的任何标准无符号整数类型(如果碰巧是无符号的则为char )。 这个假设的扩展类型不是字符类型(6.2.5p15),因此不符合对不兼容类型(6.5p7)的对象的别名访问,这让我觉得编译器编写者想要这样做的原因事情。

如果存在uint8_t ,则无填充要求意味着CHAR_BIT为8.但是,没有根本原因我可以找到为什么uint8_t不能用扩展整数类型定义。 此外,无法保证陈述相同; 例如,可以以相反的顺序解释比特。

虽然对于uint8_t来说这看起来很愚蠢而且非常不寻常,但它对int8_t来说int8_t 。 如果一台机器本身使用了一个补码或符号/幅度,那么signed char不适合int8_t 。 但是,它可以使用扩展的有符号整数类型来模拟二进制补码以提供int8_t

在6.3.1.1(1)(C11标准的N1570草案)中,我们可以阅读

任何标准整数类型的等级应大于具有相同宽度的任何扩展整数类型的等级。

因此,标准明确允许存在与标准整数类型相同宽度的扩展整数类型。

标准中没有任何内容禁止a

 typedef implementation_defined_extended_8_bit-unsigned_integer_type uint8_t; 

如果扩展的整数类型与uint8_t的规范匹配(没有填充位,宽度为8位),据我所知。

所以,是的, 如果实现提供了这样的扩展整数类型, uint8_t 可能会被类型化。

uint8_t可能存在并且是与unsigned char不同的类型。

其中一个重要的含义是过载分辨率; 它是依赖于平台的:

 uint8_t by = 0; std::cout << by; 

使用

  1. operator<<(ostream, char)
  2. operator<<(ostream, unsigned char)
  3. operator<<(ostream, int)

int8_t和uint8_t的区别仅在于REPRESENTATION而不是内容(位)。 int8_t使用低7位表示数据,第8位表示“符号”(正或负)。 因此,int8_t的范围是从-128到+127(0被认为是正值)。

uint8_t也是8位宽,但其中包含的数据总是正数。 因此uint8_t的范围是0到255。

考虑到这个事实,char是8位宽。 unsigned char也可以是8位宽但没有“符号”。 类似地,短和无符号短路都是16位宽。

但是,IF“ unsigned int ”是8位宽,那么..因为C不是太类型纳粹,所以它是允许的。 为什么编译器编写者会允许这样的事情呢? 可读性!