In C++, pre-increment operator gives lvalue because incremented object itself is returned, not a copy. But in C, it gives rvalue. Why?
-
1Its an excellent question IMHO :-) – Prasoon Saurav Jan 26 '11 at 08:29
-
http://stackoverflow.com/questions/371503/why-is-i-considered-an-l-value-but-i-is-not – Jason LeBrun Jan 26 '11 at 08:30
-
1@Jason : That question is C++ specific – Prasoon Saurav Jan 26 '11 at 08:39
-
There are a number of resources linked from that topic, including a long discussion which touches on the reasons that it doesn't work that way in C. – Jason LeBrun Jan 26 '11 at 08:41
-
I dont know a single line of C++ , but everithing on C – Mandrake Jan 29 '11 at 12:18
3 Answers
C doesn't have references. In C++ ++i
returns a reference to i
(lvalue) whereas in C it returns a copy(incremented).
C99 6.5.3.1/2
The value of the operand of the prefix ++ operator is incremented. The result is the new value of the operand after incrementation. The expression ++Eis equivalent to (E+=1).
‘‘value of an expression’’ <=> rvalue
However for historical reasons I think "references not being part of C" could be a possible reason.

- 91,295
- 49
- 239
- 345
-
But still I can't understand why it returns a copy in pre-increment. Why just not return incremented i as it does in say, i=j. Here, original i, after being changed, is returned. Similarly, in i=i+1, i, itself could be returned after being changed. – Happy Mittal Jan 26 '11 at 08:20
-
1@HappyMittal: Expressions don't really return values, they have value (or evaluate to a value) and other properties such as type and _lvalue-ness_, the expression `++i` doesn't "return" a copy, there is no copy. `++i` evaluates to the new value of `i`. There is no copy unless you use it in a larger expression that makes a copy. – CB Bailey Jan 26 '11 at 08:28
-
@Charles Bailey : Ok, I agree that in ++i evaluates to new value of i. But my question is that in i=j, i is changed and expression yields an lvalue. So ++i i.e. i=i+1 is pretty much same as i=j, then why in this case, expression doesn't yield an lvalue ? – Happy Mittal Jan 26 '11 at 08:35
-
1@Happy : "Ok, I agree that in ++i evaluates to new **value** of i" and rvalue means `**value** of an expression` (C99). `i=j` also evaluates to a value. Try taking address of `(i=j)` and you'll surely get an error – Prasoon Saurav Jan 26 '11 at 08:37
-
-
`*(++i,&i) = 10;` will work in C. You could define a macro `#define PREINC(x) *(++(x),&(x))`. (There was an error in my comment of one hour ago which I have now deleted.) – Aaron McDaid Aug 27 '12 at 11:32
-
@PrasoonSaurav C not having references doesn't help your answer. For `int x`, `decltype(*&x)` in C++ is `int&`. But `*&x` is a lvalue both in C++ as in C, even though C doesn't have `int&`. So C supports lvalues out of expressions in special cases, and hence not having references is not a good explanation for not having it for pre-increment, it's a weak argument. – oblitum Jun 17 '16 at 02:43
-
@HappyMittal the above comment is a better sample of what you tried to do with `i=j`. – oblitum Jun 17 '16 at 02:49
C99 says in the footnote (of section $6.3.2.1),
The name ‘‘lvalue’’ comes originally from the assignment expression E1 = E2, in which the left operand E1 is required to be a (modifiable) lvalue. It is perhaps better considered as representing an object ‘‘locator value’’. What is sometimes called ‘‘rvalue’’ is in this International Standard described as the ‘‘value of an expression’’.
Hope that explains why ++i
in C, returns rvalue.
As for C++, I would say it depends on the object being incremented. If the object's type is some user-defined type, then it may always return lvalue. That means, you can always write i++++++++
or ++++++i
if type of i
is Index
as defined here:
-
If the object's type is _not_ a user-defined type then pre-increment must be an _lvalue_, anyway. – CB Bailey Jan 26 '11 at 08:03
-
I am asking about behaviour in C because in C++, it makes sense to return lvalue as incremented object is to be returned. – Happy Mittal Jan 26 '11 at 08:04
-
1@Charles: hehe.. yeah. Since the OP didn't mention the type of the object, I replied only one side of the question. – Nawaz Jan 26 '11 at 08:04
-
Please check this comment, where `*&x` is referred as an expression, as well as being an lvalue: http://stackoverflow.com/questions/4802315/why-pre-increment-operator-gives-rvalue-in-c#comment63200989_4802402 – oblitum Jun 17 '16 at 02:54
-
Unfortunately, the C Standard uses the term "lvalue" both to refer to an expression, and to the "locator value" that is produced by the expression, and doesn't attach any term to the process of converting the former to the latter. If `int *p = &someAggregateArr[i++].member;` is executed when `i` is 5, then the sub-expression `someAggregateArr[i++].member` should produce a "locator value" which identifies `someAggregateArr[5].member` even though the latter is not an expression that appears anywhere in the code. – supercat Apr 24 '18 at 19:43
Off the top of my head, I can't imagine any useful statements that could result from using a pre-incremented variable as an lvalue. In C++, due to the existence of operator overloading, I can. Do you have a specific example of something that you're prevented from doing in C, due to this restriction?

- 13,037
- 3
- 46
- 42
-
-
1@Filip It's my (admittedly non-rigorous) answer to the question which was posed. The addition of overloaded operators in C++ made the pre-increment-as-lvalue construct more valuable, hence it was added. – Jason LeBrun Jan 26 '11 at 08:24
-
+1, I think this is an answer, albeit an uncertain one. Most ways to use the result of `++i` as an lvalue in C, would be undefined behavior for lack of sequence points. So it's no great loss for the syntax to forbid it, although `myfunc(&(++i))` would be alright and sometimes useful. Note also that in C, `(++i, i)` is equivalent to what `++i` would be if it evaluated to an lvalue, so even where you have a use for it, it's still no huge loss that it isn't. – Steve Jessop Jan 26 '11 at 09:41
-
Useful statement that doesn't work because pre-increment doesn't produce lvalue: circular increment a variable: `++i %= bufsize`. (I acknowledge, that you can write this differently though.) – moooeeeep Aug 27 '18 at 09:01
-
@moooeeeep: There are a few ternary compound assignment operators I'd like to see in C, but while I could see lots of uses for an operator that would store `x=(x+y)&z;` I don't see much to be gained by having the intermediate value stored before being masked with `z`. – supercat Jun 15 '19 at 19:12