强制按位使用,而不是布尔和 [英] forcing usage of bitwise and instead of boolean and

查看:110
本文介绍了强制按位使用,而不是布尔和的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在C ++中,保证布尔值为0或1

In C++, a bool is guaranteed to be 0 or 1

C++ (§4.5/4):
An rvalue of type bool can be converted to an rvalue of type int, with 
false becoming zero and true becoming one.

考虑以下功能以及g ++ 5.2用-O3生成的内容

Consider the following function and what g++5.2 generates with -O3

int foo(bool a, bool b)
{
    if(a&b) return 3;
    else return 5;
}


0000000000000000 <_Z3foobb>:
   0:   40 84 ff                test   %dil,%dil
   3:   74 13                   je     18 <_Z3foobb+0x18>
   5:   40 84 f6                test   %sil,%sil
   8:   b8 03 00 00 00          mov    $0x3,%eax
   d:   74 09                   je     18 <_Z3foobb+0x18>
   f:   f3 c3                   repz retq 
   11:  0f 1f 80 00 00 00 00    nopl   0x0(%rax)
   18:  b8 05 00 00 00          mov    $0x5,%eax
   1d:  c3                      retq   

如上所示,它正在生成两个测试指令,表明它仍将if视为if(a& b)而不是按位与.

As seen, above, it is generating two test instructions which indicates that it is still treating the if as a if(a&&b) instead of a bitwise and.

即使我首先将两个布尔值显式转换为两个字符,它仍然会产生与上述相同的输出.

Even if I first explicitly convert the two bools to two chars , it still generates the same output as above.

由于我知道两个操作数a和b只能具有0/1作为值,是否有某种方法可以使gcc生成一条测试指令.如果函数使用两个int而不是两个bool,则确实是这样做的.

Since I know that the two operands a and b can only have 0/1 as values, is there some way to get gcc to generate just one test instruction. This is indeed what it does if the function takes two ints instead of two bools.

推荐答案

有了&,某些编译器已经产生了不同的asm而没有跳转:

With &, some compiler already produces different asm without jump:

c铛3.6(rc2):

clang 3.6 (rc2):

foo(bool, bool):                               # @foo(bool, bool)
    testb   %sil, %dil
    sete    %al
    movzbl  %al, %eax
    leal    3(%rax,%rax), %eax
    retq

在您的情况下,一种破解方法是使用*,该表具有与true/false相同的true-表

A hack, in your case is to use * which has the same true-table for true/false

int foo(bool a, bool b)
{
    if (a * b) return 3;
    else return 5;
}

哪个会产生:

foo(bool, bool):
    movzbl  %sil, %esi  # b, b
    movzbl  %dil, %edi  # a, tmp70
    imull   %esi, %edi  # b, tmp70
    cmpl    $1, %edi    #, tmp70
    sbbl    %eax, %eax  # D.1960
    andl    $2, %eax    #, D.1960
    addl    $3, %eax    #, D.1960
    ret

演示

这篇关于强制按位使用,而不是布尔和的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆