未初始化的值在 Linux 上的行为符合预期,但在 Windows 上则不然

Uninitialized values behave as expected on Linux but not Windows

本文关键字:但在 Windows 初始化 Linux      更新时间:2023-10-16

为什么未初始化的"max"和"min"值在Linux上有效,而在Windows上不起作用?例如:

double max, min, test;
while (1)
{
  std::cin >> test;
  if (test > max)
    max = test;
  if (test < min)
    min = test;
}

这适用于 Linux。我知道一个事实,因为我已经在使用它(尽管直到现在我才意识到这有多可怕)至少 3 个月了。然而,许多同事告诉我,这在他们的机器上被破坏了:他们使用Visual Studio进行编译。他们的陈述是否有一些道理,为什么?这仅仅是UB的案例吗?如果是这样,过去几个月它是如何工作的,我没有注意到?

另请注意:gcc (Ubuntu/Linaro 4.5.2-8ubuntu4) 4.5.2 和 Visual Studio 2010

这"工作"不在一个平台上。

它所做的只是调用未定义的行为"似乎做了我所期望的"只是UB实现自己的一种方式。不过,这是一个相当不幸的问题,因为它让你相信你的代码很好,直到有一天它在你的客户面前爆炸。

因为未定义的行为是未定义的。它可能有效,也可能不起作用,你只是不知道。显然,在您的 Linux 环境中,它可以工作。

粗略地说,如果未初始化的变量min并且max恰好包含的值在test中遇到的实际最小值和最大值之间进行比较,则您的代码似乎可以正常工作。未初始化的自动变量的对象表示形式可能是一致的,也可能是不一致的,这取决于编译器、选项和程序其余部分的代码。读取未初始化的值肯定是 UB。UB 可能一致,也可能不一致。

例如,您可以获得观察到的行为的一种简单方法是:

  • 您的测试集都包含正值和负值,
  • GCC/Linux 始终在未初始化的变量中放置一个全位零表示,
  • VS 始终将 NaN 放入未初始化的变量中(因此 test < mintest > max 总是假的)。

根据您的测试数据以及"机器上损坏"的含义,详细信息可能会有所不同。我刚刚描述了UB无限范围中的一种可能性。

使用未初始化变量的值是未定义的行为,因此任何事情都可能发生。任何东西,这意味着代码可能看起来有效,它可能会崩溃,或者它可能导致恶魔从你的鼻子里飞出来。

相关文章: