Leo Leo - 2 months ago 11
C++ Question

Using Likely() / Unlikely() Preprocessor Macros in if-else if chain

If I have:

#define likely(x) __builtin_expect((x),1)
#define unlikely(x) __builtin_expect((x),0)

if (A)
return true;
else if (B)
return false;
...
else if (Z)
return true;
else
//this will never really happen!!!!
raiseError();
return false;


Can I put likely() around the last condition check like
else if (likely(Z))
to signify that the final statement (else) is very unlikely WITHOUT the compiler affecting the branch prediction of the previous checks?

Basically, does GCC try to optimize the entire if-else if block if there is a single conditional statement with a branch predictor hint?

Answer

You shall make this explicit:

if (A)
  return true;
else if (B)
  return true;
...  
else if (Y)
  return true;
else {
  if (likely(Z))
    return true;

  raiseError();
  return false;
}

Now compiler clearly understands your intention and will not reassign other branch probabilities. Also readability of code increased.

P.S. I suggest you to rewrite also likely and unlikely in the way Linux kernel do to protect from silent integral casts:

#define likely(x)      __builtin_expect(!!(x), 1)
#define unlikely(x)    __builtin_expect(!!(x), 0)