Search code examples
c++rvaluelvaluepost-increment

Why can't a++ (post-increment operator) be an Lvalue?


Code

#include<iostream>
int main()
{
    int a=3;
    a++=5;
    std::cout<<a;
}

Output (as expected)

[Error] lvalue required as left operand of assignment

1. The post increment operator (a++) has the highest priority in the table. So it will definitely execute before the assignment operator (=). And as per the rule of post increment the value of variable a will increment only after execution of that statement.

So what exactly happens when the post increment operator (++) executes before the assignment operator (=)?

2. In C both the pre- and post-increment operators yield rvalues but C++ updated the pre-increment operator to an lvalue while keeping the post-increment operator as an rvalue only. The reason for that is we can't make it an lvalue as it possesses only the old value, not the updated one. But I don't understand this reason properly.

See now a++ has the rvalue 3, not the variable itself, right? But what if it brings a variable which possesses an lvalue, then 5 will insert into that and after the end of the statement its value will be 6. What's the problem with this and why can't it be done?


Solution

  • And As per rule of post increment the value of variable a will increment only after execution of that statement.

    That's a bit misleading. The variable is incremented immediately. But the result of the expression is the old value. This should make it easier to understand why it cannot be an lvalue. The modified object doesn't have the old value, so the hypothetical lvalue cannot refer to that object. The value is a new, temporary object; it is a prvalue.

    As an analogy, think about writing a function that does the same thing as post increment. This is how it would be written (if you define overloaded operator overload for a class, then a function such as this is quite literally what you'd write with a few changes):

    int post_increment(int& operand)
    {
        int old = operand;
        operand += 1;
        return old;
    }
    

    How could you meaningfully re-write that function to return an lvalue (reference) and still have the behaviour expected from the post increment?