我通过这个简单的演示重现了这个问题:
// 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 mov $0x400694,%edi 4005f9: b8 00 00 00 00 mov $0x0,%eax 4005fe: e8 9d fe ff ff callq 4004a0 400603: 48 83 c4 08 add $0x8,%rsp 400607: c3 retq 400608: 0f 1f 84 00 00 00 00 nopl 0x0(%rax,%rax,1) 40060f: 00
gcc 版本 4.9.2 (Debian 4.9.2-10)
这是 g++ 设计的行为吗?我怎样才能禁用这个错误的优化? 谢谢~
最佳答案
I think it is a g++ bug.
必须尊重地不同意那里。
How can I disable this wrong optimisation?
即使这是可能的,实际上也没有错:-)
您将非 bool 指针作为 bool 指针传递(基础项不是 bool 类型),我很确定这(称为类型双关语)会调用未定义的行为。
因此代码可以随心所欲地做任何事情。
您可以将原型(prototype) void func(bool* b)
视为您同意只传递指向 bool
的指针的 contract值(value)观。如果您违反该契约(Contract),则所有赌注都将取消。在这种特殊情况下,您的代码:
int a = (*b ? 0 : 1);
告诉它将 false 转换为 1 并将 true 转换为 0。如果您要提供 valid 输入(false/0
或 true/1
),xor input, 1
将是完全正确的做法。
但是,因为您给它 128
,所以 xor
的结果是 129
。
关于c++ - g++ 错误? ( bool 值?0 : 1) returns neither 0 nor 1,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31455743/