# C/C++ math operator question

**URL:** <https://boards.straightdope.com/t/c-c-math-operator-question/287028>\
**Category:** Factual Questions\
**Created:** [January 28, 2005, 1:41am UTC](https://boards.straightdope.com/t/c-c-math-operator-question/287028 "2005-01-28T01:41:27Z")\
**Posts on this page:** 13\
**Page:** 1

<div class="post-metadata">

**Author:** ![Nobody](https://avatars.discourse-cdn.com/v4/letter/n/94ad74/32.png) [@Nobody](https://boards.straightdope.com/u/Nobody)\
**Post date:** [January 28, 2005, 1:41am UTC](https://boards.straightdope.com/t/c-c-math-operator-question/287028/1 "2005-01-28T01:41:27Z")

</div>

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.

---

<div class="post-metadata">

**Author:** ![Joe\_Random](https://avatars.discourse-cdn.com/v4/letter/j/e8c25b/32.png) [@Joe\_Random](https://boards.straightdope.com/u/Joe_Random)\
**Post date:** [January 28, 2005, 2:12am UTC](https://boards.straightdope.com/t/c-c-math-operator-question/287028/2 "2005-01-28T02:12:47Z")

</div>

> [@Master Control](#):
>
> What exactly does this mean?  
> if(A\<B\<C)

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

---

<div class="post-metadata">

**Author:** ![lno](https://avatars.discourse-cdn.com/v4/letter/l/a8b319/32.png) [@lno](https://boards.straightdope.com/u/lno)\
**Post date:** [January 28, 2005, 2:14am UTC](https://boards.straightdope.com/t/c-c-math-operator-question/287028/3 "2005-01-28T02:14:15Z")

</div>

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.

---

<div class="post-metadata">

**Author:** ![lno](https://avatars.discourse-cdn.com/v4/letter/l/a8b319/32.png) [@lno](https://boards.straightdope.com/u/lno)\
**Post date:** [January 28, 2005, 2:16am UTC](https://boards.straightdope.com/t/c-c-math-operator-question/287028/4 "2005-01-28T02:16:23Z")

</div>

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.

---

<div class="post-metadata">

**Author:** ![Nobody](https://avatars.discourse-cdn.com/v4/letter/n/94ad74/32.png) [@Nobody](https://boards.straightdope.com/u/Nobody)\
**Post date:** [January 28, 2005, 2:29am UTC](https://boards.straightdope.com/t/c-c-math-operator-question/287028/5 "2005-01-28T02:29:35Z")

</div>

Ahhh, I get it. Thanks.

---

<div class="post-metadata">

**Author:** ![bitwise](https://avatars.discourse-cdn.com/v4/letter/b/ea5d25/32.png) [@bitwise](https://boards.straightdope.com/u/bitwise)\
**Post date:** [January 28, 2005, 3:17am UTC](https://boards.straightdope.com/t/c-c-math-operator-question/287028/6 "2005-01-28T03:17:30Z")

</div>

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.

---

<div class="post-metadata">

**Author:** ![bitwise](https://avatars.discourse-cdn.com/v4/letter/b/ea5d25/32.png) [@bitwise](https://boards.straightdope.com/u/bitwise)\
**Post date:** [January 28, 2005, 3:24am UTC](https://boards.straightdope.com/t/c-c-math-operator-question/287028/7 "2005-01-28T03:24:59Z")

</div>

> [@bitwise](#):
>
> 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/](http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vclang/html/)_pluslang\_c.2b2b_.operators.asp

---

<div class="post-metadata">

**Author:** ![CaveMike](https://sea3.discourse-cdn.com/straightdope/user_avatar/boards.straightdope.com/cavemike/32/16379_2.png) [@CaveMike](https://boards.straightdope.com/u/CaveMike)\
**Post date:** [January 28, 2005, 3:31am UTC](https://boards.straightdope.com/t/c-c-math-operator-question/287028/8 "2005-01-28T03:31:48Z")

</div>

> [@lno](#):
>
> 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.

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:

```auto

void x( char * p )
{
   if ( p && ( *p == 'A' ) )
   {
      ...
   }
}

```

---

<div class="post-metadata">

**Author:** ![zippyh](https://avatars.discourse-cdn.com/v4/letter/z/839c29/32.png) [@zippyh](https://boards.straightdope.com/u/zippyh)\
**Post date:** [January 28, 2005, 3:36am UTC](https://boards.straightdope.com/t/c-c-math-operator-question/287028/9 "2005-01-28T03:36:03Z")

</div>

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

---

<div class="post-metadata">

**Author:** ![Ms2001](https://sea3.discourse-cdn.com/straightdope/user_avatar/boards.straightdope.com/ms2001/32/18463_2.png) [@Ms2001](https://boards.straightdope.com/u/Ms2001)\
**Post date:** [January 28, 2005, 4:49am UTC](https://boards.straightdope.com/t/c-c-math-operator-question/287028/10 "2005-01-28T04:49:24Z")

</div>

> [@lno](#):
>
> Either way, it is not the same as “if ((a \< b) && (b \< c))”, as you noticed.

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.

---

<div class="post-metadata">

**Author:** ![Monstre](https://avatars.discourse-cdn.com/v4/letter/m/e274bd/32.png) [@Monstre](https://boards.straightdope.com/u/Monstre)\
**Post date:** [January 28, 2005, 5:24am UTC](https://boards.straightdope.com/t/c-c-math-operator-question/287028/11 "2005-01-28T05:24:37Z")

</div>

> [@bitwise](#):
>
> It appears that \< is left associative, so Joe Random is correct.

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

> [@](#):
>
> from _CaveMike_  
> 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:

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:

```auto

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:

```auto

(a < b < c)

```

## because the operands are just variables, and the operator associates left-to-right.

> [@](#):
>
> from _Mr2001_  
> 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.

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

---

<div class="post-metadata">

**Author:** ![ultrafilter](https://avatars.discourse-cdn.com/v4/letter/u/3d9bf3/32.png) [@ultrafilter](https://boards.straightdope.com/u/ultrafilter)\
**Post date:** [January 28, 2005, 5:39am UTC](https://boards.straightdope.com/t/c-c-math-operator-question/287028/12 "2005-01-28T05:39:45Z")

</div>

> [@zippyh](#):
>
> Also, I don’t think you can count on (a\<b), evaluating to 1 when true so much as just “non-zero”.

That’s most likely compiler-dependent.

---

<div class="post-metadata">

**Author:** ![Bytegeist](https://avatars.discourse-cdn.com/v4/letter/b/9dc877/32.png) [@Bytegeist](https://boards.straightdope.com/u/Bytegeist)\
**Post date:** [January 28, 2005, 5:59am UTC](https://boards.straightdope.com/t/c-c-math-operator-question/287028/13 "2005-01-28T05:59:13Z")

</div>

> [@zippyh](#):
>
> Also, I don’t think you can count on (a\<b), evaluating to 1 when true so much as just “non-zero”.

Actually you can, if your compiler’s anything near to recent. From Harbison and Steele, 4th edition:

> [@](#):
>
> **7.6.4 Relational Operators**
> 
> \< \<= \> \>=
> 
> The usual binary conversions are performed on the operands. … The result is always of type _int_ and has the value 0 or 1. …

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