17
4

2 回答 2

17

我只是想知道为什么未初始化的布尔行为会突然发生变化?

反汇编代码,看看编译器在做什么。

我的猜测:由于该值现在仅在本地使用,编译器将其完全优化掉。由于无论如何行为是未定义的,编译器可以安全地假设任何值,例如false. 这是一个非常明显的优化,因为b就编译器而言,值是恒定的,并且整个逻辑switch是多余的。那么为什么要把它放在可执行文件中呢?

(这里重要的一点是,它b实际上只在第二个代码中本地使用,这反过来会触发更多优化,即使在未优化的代码中也是如此。在编译器可以进行任何此类优化之前,必须内联第一个代码,或者代码必须跟踪路径,这不是微不足道的)。

于 2011-02-02T19:46:47.993 回答
1

就在今天,我遇到了这个错误的一个版本。我在这里提供我的经验,以防它对其他人有所启发。

我有一些代码归结为

if(!(a == b && c.d())) { do_something(); }

我正在追逐的错误是do_something()错误地发生了。然而a,绝对等于,b并且c.d()似乎,回归真实。

当我跟踪这个时,我临时添加了这些测试打印输出:

if(  a == b && c.d() ) printf("yes\n"; else printf("no\n");
if(!(a == b && c.d())) printf("noo\n"; else printf("yess\n");

令我惊讶的是,这个打印出来yes的 andnoo既证实了do_something发生的原因,又证实了一些非常奇怪的事情正在发生。

原来这个方法d()有点像

bool whatever::d() {
    return _successful;
}

但未_successful初始化。当我打印出它的值时,它是 236,这就是为什么我之前说过“c.d()似乎返回了 true”。

我没有检查汇编代码,但我猜在某些情况下,gcc 正在测试它是否为非零,但在其他情况下,它只是测试低位。

正确初始化_successful使错误消失。(自从早期的程序员第一次编写 method 以来,它已经有十年d()未初始化了。然而直到几个月前这个 bug 才出现。这就是为什么有时,软件很难。)

于 2018-04-23T22:44:35.760 回答