4

根据 C99 标准中的以下两个条款:

6.2.5-9

有符号整数类型的非负值范围是对应无符号整数类型的子范围,相同值在每种类型中的表示是相同的。

6.2.6.2-2

对于有符号整数类型,对象表示的位应分为三组:值位、填充位和符号位。不需要任何填充位;应该只有一个符号位。作为值位的每个位应与相应无符号类型的对象表示中的相同位具有相同的值(如果有符号类型中有 M 个值位,无符号类型中有 N 个,则 M ≤ N )。

有符号类型(可能)可以表示相应无符号类型可表示的所有数字。例如,如果unsigned int使用 31 个值位和 1 个填充位表示类型,并且使用 31 个值位和无填充位表示有符号整数。

是否允许实现这样做?如果是,这是否意味着在这种情况下unsigned int将提升为 an (因为两种类型具有相同的转换等级并且可以代表所有代表的值)?intintunsigned int

4

1 回答 1

4

有符号类型(可能)可以表示相应无符号类型可表示的所有数字。例如,如果 unsigned int 类型使用 31 个值位和 1 个填充位表示,而有符号 int 类型使用 31 个值位和无填充位表示。是否允许实现这样做?

该标准规定6.3.1.8 Usual arithmetic conversions

否则,对两个操作数都执行整数提升。然后将以下规则应用于提升的操作数: 如果两个操作数具有相同的类型,则不需要进一步转换。

否则,如果两个操作数都具有有符号整数类型或都具有无符号整数类型,则具有较小整数转换等级的类型的操作数将转换为具有较高等级的操作数的类型。

否则,如果无符号整数类型的操作数的等级大于或等于另一个操作数类型的等级,则将有符号整数类型的操作数转换为无符号整数类型的操作数的类型。

由于intunsigned int具有相同的等级 ( 6.3.1.1 Boolean, characters, and integers),int将转换为unsigned int,但不是相反:

— 任何无符号整数类型的等级应等于相应的有符号整数类型的等级,如果有的话。

以 为后缀的整数常量u始终是无符号的(参见 中的表格6.4.4.1 Integer constants)。

6.3.1.1 Boolean, characters, and integers第 2 条还告诉我们:

可以在可以使用 int 或 unsigned int 的表达式中使用以下内容:

— 整数类型的对象或表达式,其整数转换等级小于 int 和 unsigned int 的等级。

— _Bool、int、signed int 或 unsigned int 类型的位域。

如果一个 int 可以表示原始类型的所有值,则将该值转换为 int;否则,它将转换为无符号整数。这些被称为整数促销。整数提升不会改变所有其他类型。

因此,不,实现不能合法地转换unsigned intint,除非您通过强制转换或分配明确要求。

编辑:第 2 条6.3.1.1 Boolean, characters, and integers内容如下:

— 整数类型的对象或表达式,其整数转换等级小于int 和 unsigned int 的等级。

(国际标准 ISO/IEC 9899 第二版 1999-12-01)

— 整数类型的对象或表达式,其整数转换等级小于或等于int 和 unsigned int 的等级。

(WG14/N1256 委员会草案 — 2007 年 9 月 7 日 ISO/IEC 9899:TC3)

— 具有整数类型(除 int 或 unsigned int 之外)的对象或表达式,其整数转换等级小于或等于int 和 unsigned int 的等级。

(N1548 委员会草案 — 2010 年 12 月 2 日 ISO/IEC 9899:201x,
N1570 委员会草案 — 2011 年 4 月 12 日 ISO/IEC 9899:201x)

只是为了好玩,C++11 的4.5 Integral promotions [conv.prom]

如果 int 可以表示源类型的所有值,则整数转换等级 (4.13) 小于 int 等级的除 bool、char16_t、char32_t 或 wchar_t 的整数类型的纯右值可以转换为 int 类型的纯右值; 否则,可以将源纯右值转换为 unsigned int 类型的纯右值。

(N3242=11-0012,
N3337 日期:2012-01-16,
国际标准 ISO/IEC 14882 第三版 2011-09-01)

于 2013-03-29T11:07:36.380 回答