2 回答
我只是想知道为什么未初始化的布尔行为会突然发生变化?
反汇编代码,看看编译器在做什么。
我的猜测:由于该值现在仅在本地使用,编译器将其完全优化掉。由于无论如何行为是未定义的,编译器可以安全地假设任何值,例如false
. 这是一个非常明显的优化,因为b
就编译器而言,值是恒定的,并且整个逻辑switch
是多余的。那么为什么要把它放在可执行文件中呢?
(这里重要的一点是,它b
实际上只在第二个代码中本地使用,这反过来会触发更多优化,即使在未优化的代码中也是如此。在编译器可以进行任何此类优化之前,必须内联第一个代码,或者代码必须跟踪路径,这不是微不足道的)。
就在今天,我遇到了这个错误的一个版本。我在这里提供我的经验,以防它对其他人有所启发。
我有一些代码归结为
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 才出现。这就是为什么有时,软件很难。)