val? 0:1)既不返回0也不返回1

我通过这个简单的演示重现了这个问题:

// 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编译并运行:

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 ++ bug,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 ++行为吗? 我怎样才能禁用这种错误的优化? 谢谢〜


我认为这是一个g ++的bug。

不得不在那里不同意。

我怎样才能禁用这个错误的优化?

即使这是可能的,但实际上并没有错:-)

你正在传递一个非布尔指针作为布尔指针(基础项目不是布尔类型),我非常肯定这(称为类型双引号)调用未定义的行为。

因此,代码可以随心所欲地做任何事情。

您可以将原型void func(bool* b)视为您同意只传递指向bool值的合约。 如果您违反该合同,所有投注都将失效。 在这个特殊情况下,你的代码:

int a = (*b ? 0 : 1);

告诉它将false转换为1,并将其转换为0.如果要提供有效的输入( false/0true/1 ), xor input, 1就是正确的选择。

然而,因为你给它128xor导致129

链接地址: http://www.djcxy.com/p/15225.html

上一篇: val ? 0 : 1) returns neither 0 nor 1

下一篇: GCC inline assembly: register constraints on intel x86