Why is ++i is l-value and i++ not?
Share
Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.
Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.
Lost your password? Please enter your email address. You will receive a link and will create a new password via email.
Please briefly explain why you feel this question should be reported.
Please briefly explain why you feel this answer should be reported.
Please briefly explain why you feel this user should be reported.
Well as another answerer pointed out already the reason why
++iis an lvalue is to pass it to a reference.The reason for the second rule is to allow to initialize a reference using a literal, when the reference is a reference to const:
Why do we introduce an rvalue at all you may ask. Well, these terms come up when building the language rules for these two situations:
The above two points are taken from the C99 Standard which includes this nice footnote quite helpful:
The locator value is called lvalue, while the value resulting from evaluating that location is called rvalue. That’s right according also to the C++ Standard (talking about the lvalue-to-rvalue conversion):
Conclusion
Using the above semantics, it is clear now why
i++is no lvalue but an rvalue. Because the expression returned is not located inianymore (it’s incremented!), it is just the value that can be of interest. Modifying that value returned byi++would make not sense, because we don’t have a location from which we could read that value again. And so the Standard says it is an rvalue, and it thus can only bind to a reference-to-const.However, in constrast, the expression returned by
++iis the location (lvalue) ofi. Provoking an lvalue-to-rvalue conversion, like inint a = ++i;will read the value out of it. Alternatively, we can make a reference point to it, and read out the value later:int &a = ++i;.Note also the other occasions where rvalues are generated. For example, all temporaries are rvalues, the result of binary/unary + and minus and all return value expressions that are not references. All those expressions are not located in an named object, but carry rather values only. Those values can of course be backed up by objects that are not constant.
The next C++ Version will include so-called
rvalue referencesthat, even though they point to nonconst, can bind to an rvalue. The rationale is to be able to ‘steal’ away resources from those anonymous objects, and avoid copies doing that. Assuming a class-type that has overloaded prefix ++ (returningObject&) and postfix ++ (returningObject), the following would cause a copy first, and for the second case it will steal the resources from the rvalue: