1

The following piece of code seems so trivial. I don't understand why its not working.

float bound_min   = +314.53f;
float bound_max   = +413.09f;
float my_variable = -417.68f;

if (bound_min <= my_variable <= bound_max)
{
    printf("Why on earth is this returning True?");
}   

Can a C++ wizard of stackoverflow please come and rescue me?

Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335
AlanSTACK
  • 5,525
  • 3
  • 40
  • 99
  • 2
    `bound_min <= my_variable` results in a boolean (in your case `false`) and `false <= bound_max` results in? – t.niese Dec 06 '19 at 05:54
  • 1
    Did you compile that with all warnings and debug info, e.g. `g++ -Wall -Wextra -g` with [GCC](http://gcc.gnu.org/) ? Did you read [*How to debug small programs*](https://ericlippert.com/2014/03/05/how-to-debug-small-programs/) ?? – Basile Starynkevitch Dec 06 '19 at 05:55
  • @t.niese So what would be the "proper" way to evaluate this inequality and make sure that `my_variable` is within bounds? – AlanSTACK Dec 06 '19 at 05:55
  • 2
    Once order of operations is applied, `if (bound_min <= my_variable <= bound_max)` -> `if ((bound_min <= my_variable) <= bound_max)` and that resolves to `if ((314.53 <= -417.68) <= 413.09)` and `if ((false) <= 413.09)`. False is 0, so `if (0 <= 413.09)` which is true. – user4581301 Dec 06 '19 at 05:56
  • @user4581301 Thank you for your response and clarification. If you post it as an answer, I would be happy to accept it. – AlanSTACK Dec 06 '19 at 05:57
  • 1
    there are a lot of duplicates: [Language support for chained comparison operators (x < y < z)](https://stackoverflow.com/q/4090845/995714), [Why can't I just use 51 <= j <= 55? / data types](https://stackoverflow.com/q/54168808/995714), [100 <= x <= 150 as argument in if (), acting funny](https://stackoverflow.com/q/9014701/995714), [Is (val1 > val2 > val3) a valid comparison in C?](https://stackoverflow.com/q/38643022/995714), [Why do most mainstream languages not support “x < y < z” syntax for 3-way Boolean comparisons?](https://softwareengineering.stackexchange.com/q/316969/98103)... – phuclv Dec 06 '19 at 06:22

2 Answers2

4

This is what happens: First

bound_min <= my_variable

Then the result (false) used for the next:

false <= bound_max

Which is true.

And the reason:

expression a() + b() + c() is parsed as (a() + b()) + c() due to left-to-right associativity of operator+

Oblivion
  • 7,176
  • 2
  • 14
  • 33
2

The condition in the if statement

if (bound_min <= my_variable <= bound_max)

is equivalent to

if ( ( bound_min <= my_variable ) <= bound_max)

The first subexpression ( bound_min <= my_variable ) evaluates to boolean false.

So as a result you have

if ( false  <= bound_max)

In this result expression the boolean false is converted to the integer 0 due to the integral promotions.

if ( 0 <= bound_max)

So the final value of the condition is true.

From the C++ 17 Standard (8.9 Relational operators)

1 The relational operators group left-to-right.

[Example: a<b<c means (a<b)<c and not (a<b)&&(b<c) —end example] .
Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335