1

Consider the following code snippet

int a,i;  
a = 5;  
(i++) = a;  
(++i) = a;  
cout<<i<<endl;

Line (++i) = a is compiling properly and giving 5 as output.
But (i++) = a is giving compilation error error: lvalue required as left operand of assignment.

I am not able to find the reason for such indifferent behavior. I would be grateful if someone explains this.

Mat
  • 202,337
  • 40
  • 393
  • 406
Shashwat Kumar
  • 5,159
  • 2
  • 30
  • 66
  • 3
    `i++` returns an rvalue of built-in type - they're not modifiable. – jrok Sep 10 '13 at 12:12
  • Duplicate of: http://stackoverflow.com/questions/371503/why-is-i-considered-an-l-value-but-i-is-not – sara Sep 10 '13 at 12:19
  • 2
    Removed C tag - neither assignments are valid in C (and obviously the last line isn't C either). Also you've got undefined behavior I believe on (i++) even if it did somehow compile, since i is uninitialized. – Mat Sep 10 '13 at 12:21
  • excellent read on lvalues and rvalues [Link](http://blogs.msdn.com/b/vcblog/archive/2009/02/03/rvalue-references-c-0x-features-in-vc10-part-2.aspx). – Koushik Shetty Sep 10 '13 at 12:24
  • @Mat On the other hand, it probably is worth pointing out that this _is_ one place where C and C++ differ. (And of course, both lines _are_ illegal in both languages. The only difference is that the second doesn't require a compiler diagnostic in C++; it's still undefined behavior.) – James Kanze Sep 10 '13 at 13:09

2 Answers2

4

The expression i++ evaluates to the value of i prior to the increment operation. That value is a temporary (which is an rvalue) and you cannot assign to it.

++i works because that expression evaluates to i after it has been incremented, and i can be assigned to (it's an lvalue).

More on lvalues and rvalues on Wikipedia.

Mike Seymour
  • 249,747
  • 28
  • 448
  • 644
Nikos C.
  • 50,738
  • 9
  • 71
  • 96
  • 5
    ah i think the lvalueness and rvalueness has been interchanged here. – Koushik Shetty Sep 10 '13 at 12:21
  • @Koushik Yep. That's what happens when your first thing in the morning isn't making coffee or brushing your teeth, but loading up a project in your IDE and then looking something up on SO, and since one thing leads to another... :-P – Nikos C. Sep 10 '13 at 12:46
  • Of course, the real reason why one is an lvalue, and the other not, is because the (C++) standard says so. But your explication does hit on the basic logic used in the standard. – James Kanze Sep 10 '13 at 13:11
0

According to the C++ standard, prefix ++ is an lvalue (which is different than C), post-fix no. More generally, C++ takes the point of view that anything which changes an lvalue parameter, and has as its value the value of that parameter, results in an lvalue. So ++ i is an lvalue (since the resulting value is the new value of i), but i ++ is not (since the resulting value is not the new value, but the old).

All of this, of course, for the built-in ++ operators. If you overload, it depends on the signatures of your overloads (but a correctly designed overloaded ++ will behave like the built-in ones).

Of course, neither (++ i) = a; nor (i ++) = a; in your example are legal; both use the value of an uninitialized variable (i), which is undefined behavior, and both modify i twice without an intervening sequence point.

James Kanze
  • 150,581
  • 18
  • 184
  • 329