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

November 5th, 2009 Leave a Comment

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 :)

Tags:
, , ,

Leave a Reply


− 1 = two