In Python, and in some other languages, the expression
a < b < c is equivalent to
a < b and b < c. For example, the following code outputs “not increasing.”
a, b, c = 3, 1, 2 if a < b < c: print "increasing" else: print "not increasing"
Now consider the analogous C code.
int a = 3, b = 1, c = 2; if (a < b < c) printf( "increasingn" ); else printf("not increasingn");
This outputs “increasing”!
If you don’t know C, you’d expect the output to be “not increasing.” If you do know C, you might expect the code not to compile.
Here’s what’s going on. The code first asks whether
a < b. This evaluates to 0 because
a < b is false. Then it asks whether
0 < c, which is true.
If the code above were part of a C++ program, it would still compile and still produce the same result. However, the compiler would generate a warning for implicitly casting Boolean result to an integer.
12 thoughts on “a < b < c”
Actually I’m not sure the C example is specified – there aren’t any sequence points if “a < b < c" so I think the compiler is allowed to treat it as "a < (b < c)" which would be "a < 1" I think.
With GCC 4.6.2, I get no warning in either C or C++. But if I turn on all warnings (-Wall) then in both C and C++, I get the following:
warning: comparisons like ‘X<=Y<=Z’ do not have their mathematical meaning [-Wparentheses]
So I am not sure your statement is entirely accurate.
I tested the code with Visual Studio 2008 in C and C++ with default warning levels but I didn’t try it on gcc.
“Trying it” with different compilers won’t tell us anything other than they (likely) each produce different results. To discern the actual differences between the languages, we should read the language specifications.
“<" is left-associative per the C standard, so "a < b < c" is the same as "(a < b) < c".
And this is another reason C’s ‘booleans’ are broken.
This is also true in SAS and other languages such as Perl 6. Some people call this an “implied AND operator.” For more details and discussion, see http://blogs.sas.com/content/iml/2012/02/20/the-data-step-and-the-implied-and-operator/
I tried it in gcc and g++. Both gives ‘increasing’ without any warning.
It is likely that clang compiler will give a warning.
In Python, and in some other languages, the expression a < b < c is equivalent to a < b and b < c
…with the difference that b is evaluated once. Hence, if b has side-effects, they are not equivalent
C doesn’t have booleans. They’re integers. So they’re not broken.
Two more data points: In Haskell, it’s a type error since there are no implicit conversions from Bool to Int. In Fortran, it’s a syntax error, because the less-than operator is not associative.
That last point is something that bugs me about a lot of programming languages. Language designers know that, say, subtraction has to be left-associative and raising-to-the-power-of has to be right-associative. But it almost doesn’t occur to them that non-associative operators are even possible, let alone sometimes desirable.