Bitwise operators vs. Boolean operators in C/C++

Writing code that uses Boolean operators are rather less efficient.

Why do I say so? Let’s look at some code for comparison.

``````bool a = true, b = true, c, d;
c = a || b;
d = a && b;``````

``````char a = 1, b = 1, c, d;
c = a | b;
d = a & b;``````

These two blocks of code look rather similar, don’t they? However, the generated assembly code varies.

Let’s look that the first block. The code will check a and b to see if they are 0 or 1. The generated assembly code by Microsoft Visual C++ looks like this.

``````    bool a = true, b = true, c ,d;
0041138E  mov         byte ptr [a],1
00411392  mov         byte ptr [b],1

c = a || b;
00411396  movzx       eax,byte ptr [a]
0041139A  test        eax,eax
0041139C  jne         wmain+42h (4113B2h)
0041139E  movzx       ecx,byte ptr [b]
004113A2  test        ecx,ecx
004113A4  jne         wmain+42h (4113B2h)
004113A6  mov         dword ptr [ebp-124h],0
004113B0  jmp         wmain+4Ch (4113BCh)
004113B2  mov         dword ptr [ebp-124h],1
004113BC  mov         dl,byte ptr [ebp-124h]
004113C2  mov         byte ptr [c],dl

d = a && b;
004113C5  movzx       eax,byte ptr [a]
004113C9  test        eax,eax
004113CB  je          wmain+71h (4113E1h)
004113CD  movzx       ecx,byte ptr [b]
004113D1  test        ecx,ecx
004113D3  je          wmain+71h (4113E1h)
004113D5  mov         dword ptr [ebp-124h],1
004113DF  jmp         wmain+7Bh (4113EBh)
004113E1  mov         dword ptr [ebp-124h],0
004113EB  mov         dl,byte ptr [ebp-124h]
004113F1  mov         byte ptr [d],dl
``````

The C code of the equivalent assembly code looks like this.

``````bool a = 1, b = 1, c ,d;

if(a == 0)
{
if(b == 0)
{
c = 0;
}
else
{
goto CTRUE;
}
}
else
{
CTRUE:
c = 1;
}

if(a != 0)
{
if(b != 0)
{
d = 1;
}
else
{
goto DFALSE;
}
}
else
{
DFALSE:
d = 0;
}
``````

As for the second block of code, the generated assembly code by Microsoft Visual C++ looks like this. Indeed, it’s very much simpler.

``````    char a = 1, b = 1, c, d;
004113F4  mov         byte ptr [a],1
004113F8  mov         byte ptr [b],1

c = a | b;
004113FC  movsx       eax,byte ptr [a]
00411400  movsx       ecx,byte ptr [b]
00411404  or          eax,ecx
00411406  mov         byte ptr [c],al

d = a & b;
00411409  movsx       eax,byte ptr [a]
0041140D  movsx       ecx,byte ptr [b]
00411411  and         eax,ecx
00411413  mov         byte ptr [d],al
``````

Hence, I’d advise you to use bitwise operators (& and |) instead of Boolean operators (&& and ||). However, do make sure the operands are either 0 or 1 for consistent results, unless you are storing multiple values (as bit flag).

Therefore, if you think that I made a mistake in my previous post regarding these algebraic reductions

• (a && b) || (!a && c) = a ? b : c
• (a && b) || (!a && c) || (b && c) = a ? b : c

Well, think again