Say you have three variables: A, B, C.
What exactly does this mean?
if(A<B<C)
I used to think it was the same as
if((A < B) && (B < C))
But then a while ago I tried using it like that, and I didn’t get the results I expected.
So how are those two comparisons different? Thanks.
What’s happening is that the program first decides if A is less than B. The result is either 1 (true) or 0 (false). It then calculates whether or not that result (e.g. the 1 or 0) is less than C. So, depending on the values of A and B, the statement if(A<B<C) really means either if(1<C) or if(0<C).
Heh - I didn’t know this offhand, so I played around a little to see what I could determine. Bear in mind that the order of evaluation inside an if (…) statement may depend on your compiler.
A statement “if (a < b)” will resolve into a boolean, which will then be compared against c. Effectively, “if (a<b<c)” is the same as “if ((1 || 0) < c)”, or, as may be the case, “if (a < (1 || 0))”.
Either way, it is not the same as “if ((a < b) && (b < c))”, as you noticed.
Doh, took too long previewing, plus I misspoke. The OR operand I used wouldn’t be part of the evaluation, as the resolution of a<b would be compared to c, not the possibilities of the resolution.
I forget whether < is left associative or right associative, and I don’t have my Harbison & Steele on me right now.
It could be (a < b) < c or a < (b < c). In either case, as others have said, the variables in the parentheses are compared to get 0 or 1, and that is compared to the variable outside the parentheses.
Just to clarify: the order of evaluation is defined in the standard and will be consistent across compilers. That is what allows you to safely do the following:
void x( char * p )
{
if ( p && ( *p == 'A' ) )
{
...
}
}
The only binary operators that associate right-to-left are the assignment operator (and other shortcut assignment operators like +=, etc.) and the ternary conditional operator ?:
All other binary operators associate left-to-right.
Actually, the order of evaluation AND (more specifically) the “short-circuit” feature of the && and || operators. If the first operand of the && operation comes out false, the second operand is not evauated at all.
However, I believe that what lno was thinking of is the fact that the language does not specify the order of the operands of any operators except for && , ||, the comma (,) operator, and the ternary ?: operator. Meaning that in code like this:
if ((x + 3) < (y - 4))
we may not be sure whether the (x + 3) will be done first, or the (y + 4). Although the precedence and associativity of the operators themselves is of course specifically defined.
So lno’s statement wouldn’t apply in the case of:
(a < b < c)
because the operands are just variables, and the operator associates left-to-right.
Not if we’re talking about the built-in types. You cannot overload operators to change the built-in definitions (like a < b if a and b are integers). Operator overloads expect at least one parameter to be a user-defined type (like a class or an enum).
Actually you can, if your compiler’s anything near to recent. From Harbison and Steele, 4th edition:
The same is true of the equality operators: == and !=.
That’s for standard C anyway, specifically C89. In C++ on the other hand, all the boolean operators return a result of type bool, which is either true or false.