Dave, thanks for your reply, your example
C absolutely guarantees that the second will NEVER be evaluated before the first. Otherwise, things like this:
if ( ptr && ptr->field )
could fail if ptr was NULL.
illustrates very helpfully why the precedence is important.
C guarantees that within the if ( b && a ) statement, a won't be evaluated if b evaluates to zero.
If you coded if ( 0 && func() ) then func will NEVER be called. if you coded if ( func() && 0 ) then I think that func will always be called since it won't evaluate the 0 until after the left hand side of the && has been evaluated.
This was actually my understanding, hence the confusion about the 'unlikely' on the second operand only. I'm sorry, I don't think I explained myself very well. With if (a && unlikely(b)) where a is false and b is false, the b will never be reached - so it really doesn't matter whether it's 'unlikely' or not. However, where a is true, even if a is not 'unlikely', b must still be evaluated anyway to find the result. So I couldn't understand how the branch optimization would be effective. if(unlikely(a) && b) or if(unlikely(a) && unlikely(b)) seems to make more sense (from a branch optimization point of view) if the result of if(...) is in doubt? If this were ||, and if I understand C's evaluation behaviour correctly, e.g. if(a || unlikely(b) || unlikely(c)) evaluation is dropped as soon as a value of true is obtained, so I could see the point (as b is still evaluated if a == 0 but not if a == 1). If a==1 is the more likely scenario, it makes sense to put it first. I might simply not be understanding properly what 'likely' and 'unlikely' actually do, please let me know if you think that's the case and I'll look around some more. Cheers Julie