Consider the following:
inline unsigned int f1(const unsigned int i, const bool b) {return b ? i : 0;}
inline unsigned int f2(const unsigned int i, const bool b) {return b*i;}
The syntax of f2 is more compact, but do the standard guarantees that f1 and f2 are strictly equivalent ?
Furthermore, if I want the compiler to optimize this expression if b and i are known at compile-time, which version should I prefer ?
Well, yes, both are equivalent.
boolis an integral type andtrueis guaranteed to convert to1in integer context, whilefalseis guaranteed to convert to0.(The reverse is also true, i.e. non-zero integer values are guaranteed to convert to
truein boolean context, while zero integer values are guaranteed to convert tofalsein boolean context.)Since you are working with unsigned types, one can easily come up with other, possibly bit-hack-based yet perfectly portable implementations of the same thing, like
although a decent compiler should be able to choose the best implementation by itself for any of your versions.
P.S. Although to my great surprise, GCC 4.1.2 compiled all three variants virtually literally, i.e. it used machine multiplication instruction in multiplication-based variant. It was smart enough to use
cmovneinstruction on the?:variant to make it branchless, which quite possibly made it the most efficient implementation.