C/C++ math operator question

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.

Or, just look at what Joe Random said.

Ahhh, I get it. Thanks.

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.

It appears that < is left associative, so Joe Random is correct.
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vclang/html/pluslang_c.2b2b.operators.asp

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' ) )
   {
      ...
   }
}


Also, I don’t think you can count on (a<b), evaluating to 1 when true so much as just “non-zero”.

If you really wanted it to work that way, I’m sure you could make it work by getting a little crazy with operator overloading and templates.

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

That’s most likely compiler-dependent.

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.