【发布时间】:2015-10-05 23:44:57
【问题描述】:
我通过这个简单的演示重现了这个问题:
// bool_test_func.cpp
#include <stdio.h>
void func(bool* b) {
int a = (*b ? 0 : 1);
printf("%d\n", a); // EXPECT ether 0 or 1 here
}
// bool_test.cpp
void func(bool* b);
int main() {
int n = 128;
func((bool*)&n);
return 0;
}
-O0编译运行:
g++ -g -O0 -Wall -o bool_test bool_test.cpp bool_test_func.cpp
mikewei@maclinux:~/testing/c++$ ./bool_test
0
-O1编译运行(意外结果):
g++ -g -O1 -Wall -o bool_test bool_test.cpp bool_test_func.cpp
mikewei@maclinux:~/testing/c++$ ./bool_test
129
当我检查-O2 ASM代码时,我认为这是一个g++错误,g++的优化代码总是认为bool值是ether 1或0:
00000000004005e6: 4005e6: 48 83 ec 08 sub $0x8,%rsp 4005ea: 0f b6 37 movzbl (%rdi),%esi 4005ed: 83 f6 01 xor $0x1,%esi #just XOR the bool val 4005f0: 40 0f b6 f6 movzbl %sil,%esi 4005f4: bf 94 06 40 00 移动 $0x400694,%edi 4005f9: b8 00 00 00 00 移动 $0x0,%eax 4005fe: e8 9d fe ff ff callq 4004a0 400603: 48 83 c4 08 添加 $0x8,%rsp 400607:c3 retq 400608: 0f 1f 84 00 00 00 00 nopl 0x0(%rax,%rax,1) 40060f: 00gcc 版本 4.9.2 (Debian 4.9.2-10)
这是 g++ 设计的行为吗?我怎样才能禁用这个错误的优化? 谢谢~
【问题讨论】:
-
有趣的
#include. -
优化没有错:bool 只能包含 0 或 1。你传入的是一个
int类型双关语作为bool,随之而来的是未定义的行为。 -
相当大胆的声明,这是一个 gcc 错误...
-
不确定我是否同意欺骗关闭的原因,假设原始实际上是由于未初始化的变量,与类型双关引起的 ub 无关。
-
不确定我是否赞成将其作为 UB 的一个很好的例子,还是反对 UB 和对这种“错误优化”的傲慢以及 C 标头和强制转换的使用?