val ? 0 : 1) returns neither 0 nor 1
I reproduce the problem by this simple demo:
// bool_test_func.cpp
#include <stdio.h>
void func(bool* b) {
int a = (*b ? 0 : 1);
printf("%dn", 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 compile and run:
g++ -g -O0 -Wall -o bool_test bool_test.cpp bool_test_func.cpp
mikewei@maclinux:~/testing/c++$ ./bool_test
0
-O1 compile and run (unexpected result):
g++ -g -O1 -Wall -o bool_test bool_test.cpp bool_test_func.cpp
mikewei@maclinux:~/testing/c++$ ./bool_test
129
When I check the -O2 ASM code, I think it is a g++ bug, g++'s optimzation code always think the bool value is ether 1 or 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 version 4.9.2 (Debian 4.9.2-10)
Is this g++ behavior by design? How can I disable this wrong optimaztion? Thanks~
I think it is a g++ bug.
Have to respectfully disagree there.
How can I disable this wrong optimisation?
Even if that is possible, it's not actually wrong :-)
You are passing a non-bool pointer as a bool pointer (the underlying item is not of the bool type) and I'm pretty certain that this (known as type punning) invokes undefined behaviour.
Hence the code is free to do whatever it wants.
You can think of the prototype void func(bool* b)
as a contract you agree to to only ever pass pointers to bool
values. If you violate that contract, all bets are off. In this particular case, your code:
int a = (*b ? 0 : 1);
is telling it to convert false to 1 and true to 0. If you were to supply valid input ( false/0
or true/1
), the xor input, 1
would be exactly the right thing to do.
However, because you're giving it 128
, the xor
results in 129
.
上一篇: PeekMessage()抛出未处理的异常(访问冲突)
下一篇: val? 0:1)既不返回0也不返回1