【问题标题】:gcc "overflow in expression" while equivalent equivalent expression works finegcc“表达式溢出”,而等效的等效表达式工作正常
【发布时间】:2016-05-19 16:50:41
【问题描述】:

这是我的代码

#include <iostream>
static const unsigned long long int xx = (36 * 36 * 36 * 36) * (36 * 36 * 36 * 36);
static const unsigned long long int y = 36 * 36 * 36 * 36;
static const unsigned long long int yy = y * y;

int main()
{
  std::cout << xx << std::endl;
  std::cout << yy << std::endl;
  return 0;
}

这是编译输出

# g++ -std=c++11 test.cpp -o test
test.cpp:2:62: warning: integer overflow in expression [-Woverflow]
 static const unsigned long long int xx = (36 * 36 * 36 * 36) * (36 * 36 * 36 * 36);

这是执行输出

# ./test
18446744073025945600
2821109907456

您能解释一下为什么我会看到此警告和不同的结果吗?如果 36 可以适合 char 那么 36^8 可以适合 unsigned long long int 所以我不确定这里有什么问题,请告知。 (我使用的是 gcc 4.9.2)

【问题讨论】:

  • 这似乎是一个非常普遍的误解:后来的意图以某种方式影响了早期代码的含义。 (这里的“earlier”和“later”指的是子表达式包含顺序。)C++ 中通常不是这种情况;最接近这样的效果的是在强制转换中的地址操作数上的重载决议。

标签: c++ c++11 gcc


【解决方案1】:
static const unsigned long long int xx = (36 * 36 * 36 * 36) * (36 * 36 * 36 * 36);

36 的类型为 int

36 * 36 的类型为 int

(36 * 36 * 36 * 36) 的类型为 int

(36 * 36 * 36 * 36) * (36 * 36 * 36 * 36) 具有 int 类型并溢出,这实际上是有符号类型的未定义行为。

你可能想要

static const unsigned long long int xx = (36ull * 36 * 36 * 36) * (36 * 36 * 36 * 36);

至于第二种情况:

static const unsigned long long int yy = y * y;

y 的类型为 unsigned long long

y * y 的类型为 unsigned long long,因此不会溢出。

【讨论】:

  • 错字 - 无符号类型的未定义行为 - 你的意思是有符号的,对吧?
猜你喜欢
  • 1970-01-01
  • 2016-04-23
  • 2020-02-01
  • 1970-01-01
  • 2016-10-14
  • 2010-09-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多