【问题标题】:unsigned integer overflow error in gcc(TDM-GCC)?gcc(TDM-GCC)中的无符号整数溢出错误?
【发布时间】:2014-09-02 23:41:15
【问题描述】:
#include <iostream>
#include <climits>
#include <cinttypes>
using namespace std;

int main()
{
    uint16_t i = 0;
    cout << USHRT_MAX << '\n' << i - 1 << '\n';
    return 0;
}

输出

65535
-1

我期望两个相等的输出,但事实并非如此。这不是不符合标准的行为吗?

*系统:Windows7

*编译选项:g++ -o $(FileNameNoExt) $(FileName) -std=c++11 -Wall -Wextra

【问题讨论】:

  • 这绝对是重复的。但是我很难找到一个好的目标。

标签: c++ gcc integer-overflow


【解决方案1】:

当 C++ 看到表达式时

i - 1

它会自动将 i 和 1 提升为 int 类型,因此表达式的结果是 int,因此输出为 -1。

要解决此问题,请将表达式的整体结果转换回 uint16_t,或执行类似的操作

i--;

就地修改i,然后打印i

希望这会有所帮助!

【讨论】:

  • cout
  • IIRC,C++ 中的所有整数计算都是通过将操作数提升为ints 或unsigned ints 来完成的,因此减去两个uint16_t 得到的表达式类型应该是intunsigned int。如果你强制转换整个表达式,那么你强制类型回到uint16_t
  • @xiver77:这个答案在原因上有些错误。 1 的类型不是原因。原因是默认促销。 C 和 C++ 实际上都不支持使用小于 int 的类型执行 any 算术。
  • 在 C 中,应用整数提升的情况是:“作为通常算术转换的一部分,到某些参数表达式,到一元 +、- 和 ~ 运算符的操作数,以及移位运算符的两个操作数"
  • “通常的算术转换”是指确定二元算术运算符的通用类型的过程。每个运算符都指定它是否执行这些转换(二进制 + 执行)。
【解决方案2】:

ii - 1 的求值之前被提升为int,因此表达式i - 1 本身被求值为有符号整数(int),试试:

cout << USHRT_MAX << '\n' << (uint16_t)(i - 1) << '\n';

Live Demo

【讨论】:

    猜你喜欢
    • 2017-08-10
    • 2015-04-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-02-24
    • 1970-01-01
    相关资源
    最近更新 更多