【问题标题】:Undefined Behaviour in C++ [duplicate]C ++中的未定义行为[重复]
【发布时间】:2019-03-22 10:54:02
【问题描述】:

我是从 Facebook 帖子中得到的。这里发生了什么事?查看 ideone 中的输出。输出超过10行。

代码:

#include<iostream> 
using namespace std;

int main()
{
    for (int i = 0; i < 10; ++i)
        cout << i*1000000000 << endl;
}

Ideone Link

【问题讨论】:

  • 你甚至用overflow标记了它。 9*1000000000 不再适合 int,这会导致溢出,这是未定义的行为。
  • 为什么不能将输出复制粘贴到您的问题中?为什么你认为这是错误的或UB?请阅读how to ask good questions,以及this question checklist
  • 可能是编译器逻辑:“由于3 * 1000000000 溢出,我们可以假设i &lt; 3。因此i &lt; 10总是正确的。”
  • 对于 16 位 int,3 * 1000000000 将在 i == 1 时溢出。因此编译器可以假设i 始终为零,并且条件i &lt; 10 始终为真。对于 32 位 int,编译器可以假定为 i &lt; 3。对于 64 位 int,循环只会运行十次。

标签: c++ undefined overflow


【解决方案1】:

您的平台很可能具有 32 位 int。所以1'000'000'000int,编译器也会尝试将i * 1'000'000'000 评估为int。这会导致从 i 开始溢出 3。

有符号整数类型溢出的行为未定义。

请注意,这会使 整个程序 的行为未定义,这导致了您观察到的多行输出(超过 10 行)。

(如果您选择了10'000'000'000 ,那么乘法将使用long long 类型进行评估,并且行为将被明确定义!)

【讨论】:

  • 我知道 UB 是什么,但不知何故,它总是可以解释实际发生的事情。你能想出这个特定平台(ideone)导致它运行超过 10 个的原因吗?
  • 所以由于未定义的行为,当 i >= 10 时,i
  • @Inam:我最疯狂的猜测是编译器假设i * 1000000000 可以 适合int,因此i 必须很小,因此少于 10 个。
  • @Inam 关键是由于未定义的行为;整个程序崩溃了。描述程序应该做什么的语言是无效的。您已经在那里编写了一个循环,但编译器可能会也可能不会决定将其设为循环;但是编译器可能会检测到它只需要在值溢出之前执行 3 次循环......然后将其他 7 次 bin
猜你喜欢
  • 2021-05-14
  • 1970-01-01
  • 2019-05-04
  • 1970-01-01
  • 2017-02-15
  • 2018-01-06
  • 2014-11-21
相关资源
最近更新 更多