强制按位使用,而不是布尔和 [英] forcing usage of bitwise and instead of boolean and
问题描述
在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屋!