【问题标题】:Integer conversion rank of signed and unsigned int有符号和无符号int的整数转换等级
【发布时间】:2012-11-18 07:33:21
【问题描述】:

例如,如果我有,

 int a = 42;
 unsigned b = 10;
 int c = a + b;

对于此语句,int c = a + b; 将首先将a 转换为unsigned int,还是将b 转换为signed intunsigned intsigned 都具有相同的转换排名,那么我们如何知道哪一个会被转换?有标准规则吗?

【问题讨论】:

标签: c c99


【解决方案1】:

简短回答:根据 C99 6.3.1.8-p1,as 值将转换为无符号整数,根据 C99 6.3.1.3-p2,添加 UINT_MAX+1 直到它落在允许的范围内通过unsigned int。由于它已经在该范围内,因此不会执行添加。在 C99 6.3.1.3-p3 中,如果 (p1) 和 (p2) 不适用,则分配回 int c 的结果将由实现定义。但在这种情况下,请注意 6.3.1.3-p1 的“值”子句。本例中的值(52)可以int表示,所以没有改变,定义的。

C99 6.3.1.3 有符号和无符号整数

  1. 当整数类型的值转换为_Bool以外的其他整数类型时,如果该值可以用新类型表示,则不变。

  2. 否则,如果新类型是无符号的,则在新类型可以表示的最大值的基础上反复加减一,直到该值在新类型的范围内。 60)

  3. 否则,新类型是有符号的,值不能在其中表示;结果要么是实现定义的,要么是产生实现定义的信号。

C99 6.3.1.8 常用算术转换

许多期望算术类型的操作数的运算符会以类似的方式导致转换和产生结果类型。目的是确定操作数和结果的通用实数类型。对于指定的操作数,每个操作数都在不改变类型域的情况下转换为对应的实数类型是公共实数类型的类型。除非另有明确说明,否则公共实数类型也是结果的对应实数类型,如果它们相同,则其类型域是操作数的类型域,否则为复数。这种模式称为通常的算术转换

首先,如果任一操作数对应的实数类型为 long double,则将另一个操作数转换为对应实数类型为 long double 的类型,而不改变类型域。

否则,如果任一操作数对应的实数类型为双精度,则另一操作数在不改变类型域的情况下转换为对应实数类型为双精度的类型。

否则,如果任一操作数对应的实数类型为float,则将另一个操作数转换为对应实数类型为float的类型,而不改变类型域。62)

否则,整数提升将在两个操作数上执行。然后将以下规则应用于提升的操作数:

  • 如果两个操作数的类型相同,则不需要进一步转换。

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

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

  • 否则,如果带符号整数类型的操作数的类型可以表示无符号整数类型的操作数类型的所有值,则将无符号整数类型的操作数转换为操作数的类型带符号整数类型。

  • 否则,两个操作数都转换为无符号整数类型,对应带符号整数类型的操作数类型。

【讨论】:

  • 一般情况下,转换为有符号的结果可以由实现定义。在这种特定情况下,它被定义,因为右侧的值 52 可以表示为 int
  • @EricPostpischil 是的。我只记得这一点,并且大约在您发布此内容的同时进行更新。由于this recent answer另一个问题,我只熟悉标准的那部分。
  • @EricPostpischil:不幸的是,当我阅读您对此问题的评论时,用户删除了他对这个问题的回答。您可以将其发布为答案或评论吗?
  • @WhozCraig:关于“定义的实现”有什么要求?例如,是否可以明确指定将signed char 设置为-128 到+127 范围之外的值的效果将是一个低位正确且高位可以任意变化的值,或者需要实现与高位一致的事情吗?
  • @WhozCraig:至少在规范的早期版本中,我对“定义的实现”的理解是,实现应该是一致的,但要求编译器一致地执行越界转换可能会损害表现。考虑shortVar = uvar1 + uvar2;。如果shortVar 在 RAM 中,这样的语句自然会去掉高位,但如果它在寄存器中,让它去掉高位可能需要额外的几条指令。是否需要符合标准的编译器来添加此类指令?
猜你喜欢
  • 2018-08-14
  • 1970-01-01
  • 2013-02-16
  • 1970-01-01
  • 2012-01-09
  • 2011-06-14
  • 1970-01-01
相关资源
最近更新 更多