c++ - 当二元运算符两边的符号不同时,提升规则如何工作?

标签 c++ overflow arithmetic-expressions integer-promotion

考虑以下程序:

// http://ideone.com/4I0dT
#include <limits>
#include <iostream>

int main()
{
    int max = std::numeric_limits<int>::max();
    unsigned int one = 1;
    unsigned int result = max + one;
    std::cout << result;
}

// http://ideone.com/UBuFZ
#include <limits>
#include <iostream>

int main()
{
    unsigned int us = 42;
    int neg = -43;
    int result = us + neg;
    std::cout << result;
}

+ 运算符如何“知道”哪个是要返回的正确类型?一般规则是将所有参数转换为最宽的类型,但这里 intunsigned int 之间没有明确的“赢家”。在第一种情况下,必须选择 unsigned int 作为 operator+ 的结果,因为我得到了 2147483648 的结果。在第二种情况下,它必须选择 int,因为我得到了 -1 的结果。然而,在一般情况下,我看不出这是如何确定的。这是我看到的未定义行为还是其他?

最佳答案

第 5/9 节明确概述了这一点:

Many binary operators that expect operands of arithmetic or enumeration type cause conversions and yield result types in a similar way. The purpose is to yield a common type, which is also the type of the result. This pattern is called the usual arithmetic conversions, which are defined as follows:

  • If either operand is of type long double, the other shall be converted to long double.
  • Otherwise, if either operand is double, the other shall be converted to double.
  • Otherwise, if either operand is float, the other shall be converted to float.
  • Otherwise, the integral promotions shall be performed on both operands.
  • Then, if either operand is unsigned long the other shall be converted to unsigned long.
  • Otherwise, if one operand is a long int and the other unsigned int, then if a long int can represent all the values of an unsigned int, the unsigned int shall be converted to a long int; otherwise both operands shall be converted to unsigned long int.
  • Otherwise, if either operand is long, the other shall be converted to long.
  • Otherwise, if either operand is unsigned, the other shall be converted to unsigned.

[Note: otherwise, the only remaining case is that both operands are int]

在您的两种情况下,operator+ 的结果都是 unsigned。因此,第二种情况实际上是:

int result = static_cast<int>(us + static_cast<unsigned>(neg));

因为在这种情况下 us + neg 的值不能由 int 表示,所以 result 的值是实现定义的 - § 4.7/3:

If the destination type is signed, the value is unchanged if it can be represented in the destination type (and bit-field width); otherwise, the value is implementation-defined.

关于c++ - 当二元运算符两边的符号不同时,提升规则如何工作?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6770258/

相关文章:

c++ - 如何使用 visual studio 构建可替换的 DLL?

c++ - 如何以编程方式编写一些 RTF 格式的 unicode 文本?

vba - 在 VBA 中计算常量时溢出

java - 乘法是否可以进行短路评估?

C++ 初学者 : Returning a single value. 问题:我的金额四舍五入,我不希望它四舍五入

c++ - 使用 Iterator 解析 Boost::Spirit Grammars

css - 较小 div 内表格的 HTML/CSS 自动宽度,溢出可见

Jquery UI - 从显示中获取一个元素 :hidden element when dragging

c - 添加字符串和 ssize_t?

java - 双重运算的错误输出