-2

when i am executing this program:

#include<iostream>
using namespace std;
int main(){
    int x=5,y=9;

    if(++x=y++){
        cout<<"Works "<<x;
    }
    else{
        cout<<"No";
    }
    return 0;
}

it works fine and the output is: Works 9

but if i execute:

  #include<iostream>
using namespace std;
int main(){
    int x=5,y=9;

    if(x++=y++){
        cout<<"Works "<<x;
    }
    else{
        cout<<"No";
    }
    return 0;
}

it states: In function 'int main()': 6:11: error: lvalue required as left operand of assignment if(x++=y++){

5 Answers5

5

Because x++ isn't an lvalue.

More specifically, x++ increments x, then returns a temporary with the original value of x. A temporary object can't (casts of dubious legality aside) be used on the left hand side of an assignment, so it is not an lvalue.

++x increments x and returns a reference to x (with its new value). You can then assign directly to it if you choose, so it is an lvalue.

However, it is possible you actually meant to compare the two expressions for equality, rather than do an assignment. In which case, you need to use == rather than =.

BoBTFish
  • 19,167
  • 3
  • 49
  • 76
2

You have to remember that the suffix increment operator returns the old value, before the increment.

This value is a very temporary value, and as all other temporary values it is not an "lvalue", i.e. it is not something that can be assigned to.

The prefix increment operator does its increment operation, and then return a reference to the new value. For ++x it returns a reference to x. It is an "lvalue".

The same of course goes for the decrement (--) operator.

There are many sources all over the Internet that will help you understand the difference between "lvalues" and "rvalues" (temporaries).

Some programmer dude
  • 400,186
  • 35
  • 402
  • 621
  • Have I missed something? How is the first example not UB? – Martin Bonner supports Monica Jan 12 '17 at 08:05
  • @MartinBonner It would be if it was e.g. `++x=x++` then yes it would be UB. But now the OP is using two different variables so it's okay. – Some programmer dude Jan 12 '17 at 08:17
  • ?? Why? There is the increment of x, and there is the assignment to x. That's two modifications and no intervening sequence point (or whatever the equivalent terminology in C++11 onward is). – Martin Bonner supports Monica Jan 12 '17 at 08:36
  • @MartinBonner Here it's a question about normal [operator precedence](http://en.cppreference.com/w/cpp/language/operator_precedence). The increment operators have much higher precedence than assignment, and therefore will be done first. The prefix increment operator returns a reference to the incremented `x`, and this reference can be used as the left-hand side of an assignment normally. – Some programmer dude Jan 12 '17 at 08:39
  • No, that's *definitely* wrong. operator precedence defines what is being operated on (eg `a / b + c` means the operands to `/` are `a` and `b`, not `b+c`), not the ordering of side effects. I will have to look up the wording and quote the relevant sections in my answer. – Martin Bonner supports Monica Jan 12 '17 at 11:26
  • @MartinBonner In my mind `++x = y++` is equivalent to `(++x) = y++`, which is why I claim that it's a operator precedence issue. I might be wrong of course (I have been wrong before :)) and will gladly admit defeat if you are able to find something to back you up. – Some programmer dude Jan 12 '17 at 11:34
1

x++ returns x, and then increments x. On the other hand, ++x increments x, and then returns it.

The second case makes sense; x is being returned, and you can do whatever. The first case makes no sense at all; x++ isn't a value. In fact, once you get back the value, x is no longer that value.

Victor Tran
  • 516
  • 4
  • 16
1

As everybody else has explained, the value of x++ is a temporary containing the old value of x, and temporaries cannot be assigned to. The compiler therefor rejects the code as not conforming to the grammar of C++.

The problem you have is that the first example is also wrong. Although ++x is grammatically an lvalue, if you put it on the left hand side of an assignment operator, you are both incrementing x and assigning to x, and it's not clear what you meant to happen. C++89 and C have the concept of sequence points, and if you modify the same variable twice without an intervening sequence point - the behaviour of the program is not defined (anything can happen - including replacing the whole function with return, or a segfault).

C++11 introduced a different terminology which I am not familiar with, but the effect in this case is the same - your first example is undefined behaviour.

0

Add some brackets according to operator precedence to see what is going on:

(++x) = (y++)

This increments x, increments y and assigns y-1 (previous value of y before the increment) to x (y++ evaluates to y, since it is a post-increment here)

(x++)=(y++)

This here isn't a valid statement, since x++ doesn't have an lvalue.

See also: Why is ++i considered an l-value, but i++ is not?

Community
  • 1
  • 1
Florian Castellane
  • 1,197
  • 2
  • 14
  • 38