Madiyar's blog

By Madiyar, 9 years ago, In English

I use python a lot. So, by accidentally I can type this code and compiler won't give me a error:

#include <iostream>
using namespace std;

int main() {
	cout << (1 <= 2 <= 1);
}

In python, and some other languages, the expression a <= b <= c is equivalent to a <= b and b <= c. But in c++, this code produces 1 (true).

Why it compiles successfully? And why it prints 1?

Hope this blog will prevent someone from possible future mistakes.

Tags c++
  • Vote: I like it
  • +73
  • Vote: I do not like it

»
9 years ago, # |
  Vote: I like it +82 Vote: I do not like it
1 <= 2 <= 1
is (1 <= 2) <= 1 for the compiler
and its equivalent to (1 <= 1)
so its true :)
»
9 years ago, # |
  Vote: I like it +83 Vote: I do not like it

Use -Wall, Luke.

hax.cpp: In function 'int main()':
hax.cpp:35:18: warning: comparisons like 'X<=Y<=Z' do not have their mathematical meaning [-Wparentheses]
  cout << (1 <= 2 <= 1) << endl;
»
9 years ago, # |
  Vote: I like it -10 Vote: I do not like it

By the way, do you use PyQt? What is your preferred method of making a static build of an application?

»
9 years ago, # |
  Vote: I like it +7 Vote: I do not like it

I use pascal a lot. So, by accidentally I can type this code and compiler won't give me a error:

#include <iostream>
using namespace std;

int a; // a = 0 by default

int main() {
    cout << (a = 1);
}

In pascal, and some other languages, the expression a = 1 is equivalent to check if the variable a has the value 1. It must be false since a = 0 by default, but in c++, this code produces 1 (true).

Why it compiles successfully? And why it prints 1?

  • »
    »
    9 years ago, # ^ |
    Rev. 2   Vote: I like it +3 Vote: I do not like it

    cout << (a = 1); gets split as a = 1 followed by cout << a;.
    a = 1 assigns the value 1 to a, and then cout << a; prints the value of a. therefore the output comes as 1.

    to do what u want, change cout << (a = 1); to cout << (a == 1);. the output will be 0.

  • »
    »
    9 years ago, # ^ |
      Vote: I like it +8 Vote: I do not like it

    It's rather a design decision. In C++ the '=' operator is usually defined as follows (yeah, it's a simplification of what really can happen):

    [type]& [type]::operator=([type] other);
    // for example... (as operator= for 'int' would be defined if it was a class)
    int& int::operator=(int other);
    

    What happens there? We assign other to this and return the reference to this. This way, you can write:

    int a, b, c;
    a = b = c = 42;
    

    It is interpreted as a = (b = (c = 42)) and means: assign 42 to c, return reference to c; assign value of c to b, return reference to b; assign value of b to a, return reference to a; this way all three variables are now equal to 42. But... yes, it leads to some trouble. Thus some people tend to write something like

    int main(){
        std::cout << (1 = a);  // or (1 == a)
    }
    

    (that is, a non-variable element is on the left-hand side). If you accidentally omit one =, you'll get a compilation error.

    • »
      »
      »
      9 years ago, # ^ |
        Vote: I like it +19 Vote: I do not like it

      Reds cannot into sarcasm...

»
9 years ago, # |
  Vote: I like it +1 Vote: I do not like it

It is evaluated left to right so when first condition returns 1 it is left with 1<=1 which also returns 1.