为什么在C语言中,每种有符号的整数类型都必须有一个对应的无符号整数类型?

8
我在阅读《C语言核心技术》时发现了这个内容:
“如果定义了一个可选的有符号类型(没有前缀u),那么相应的无符号类型(以字母u开头)是必需的,反之亦然。”
该段落涉及到C99标准中的精确宽度整数类型。

对于一个有趣的问题加一。简短的答案是我没有任何头绪。它还排除了一个可以轻松实现uint32_t但不易实现int32_t的奇异系统能够指定任意一个的可能性。 - Bathsheba
2
因为标准规定如此。为什么标准要这样规定呢?因为精确宽度类型的行为几乎相同,无论它们是有符号还是无符号,如果不这样做会很奇怪。 - Art
1
无符号版本始终可行,即使这意味着仅具有有符号对应项的正数范围。(符号位变成填充位-现在很少这样做。)这不适用于没有填充的_精确宽度_类型。 - chux - Reinstate Monica
1个回答

5
由于C语言的原始数据类型有带符号和无符号版本。从C99的论述中,它们解释了需要 inttypes/stdint 类型的原因,C99 rationale V5.10 7.8如下所示:
C89 规定该语言应支持四种有符号和无符号整数数据类型:char、short、int 和 long,但除了 int 和 short 至少为 16 位、long 至少与 int 一样长且不小于 32 位之外,对它们的大小几乎没有什么要求。对于 16 位系统,大多数实现将 8、16、16 和 32 位分配给 char、short、int 和 long。对于 32 位系统,通常的做法是将这些类型分配为 8、16、32 和 32 位。整数类型的 int 大小差异可能会给那些从一个分配不同大小整数类型的系统迁移的用户带来一些问题,因为标准 C 的整数提升规则可能会产生意外的静默更改。随着 64 位系统的引入,定义扩展整数类型的需求增加了。
<inttypes.h> 的目的是提供一组整数类型,其定义在各种机器上是一致的,并且独立于操作系统和其他实现特定信息。它通过 typedef 定义了各种大小的整数类型。实现可以将它们 typedef 为标准 C 整数类型或扩展它们支持的类型。一致使用此头文件将极大地增加用户程序在平台之间的可移植性。
这些类型的实现意图是可能通过 typedef 进行执行。因此,需要有一个与每个支持的原始数据类型相对应的固定宽度类型。
至于为什么 C 具有带符号类型,那只是因为 CPU 支持带符号和无符号数字算术运算。但也因为我们希望使用整数类型来表示存储的原始二进制数据:类型 unsigned char/uint8_t 是 C 语言中相当于可以包含任何内容的原始数据字节。 (这就是字符类型不能包含任何陷阱表示等的原因。)
从 C99 标准本身,我们可以找到与您的书中类似的文本,C99 6.2.5/6:
对于每个有符号整数类型,都有一个对应的(但不同的)无符号整数类型(使用关键字 unsigned 标记),它使用相同的存储空间(包括符号信息)并具有相同的对齐要求。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接