Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

postfix (prefix) increment, L-value and R-value (in C and C++)

I just learned the following facts:

  • The result of a prefix increment (++var_name) is an R-value in C (at least, I am sure that it is not a L-value in C), but it is an L-value in C++.

  • The result of a postfix increment (var_name++) is an R-value in C (at least, I am sure that it is not a L-value in C). This is also true in C++ (It says the result is a prvalue).

I checked these in VS2010 (.cpp and .c) and Ubuntu (gcc and g++).

In p.109 (5.3.2) of C++ Standard http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2011/n3242.pdf, it is written

The operand of prefix ++ is modified by adding 1, or set to true if it is bool (this use is deprecated). The operand shall be a modifiable lvalue. The type of the operand shall be an arithmetic type or a pointer to a completely-defined object type. The result is the updated operand; it is an lvalue, and...

and in p.101, (5.2.6)

The value of a postfix ++ expression is the value of its operand. ... The result is a prvalue. The type of the result is the cv-unqualified version of the type of the operand. See also 5.7 and 5.17.

(I don't know the difference between R-value and prvalue though).

As to C standard http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1570.pdf, prefix ++ is described in 6.5.3.1 and postfix is in 6.5.2.4, but from the description, I can't get a clear, definite answer.

I would like to know the reasons that make them being R-value or L-value. All I know is that

We can assign a value to a (modifiable) L-value, for example, a variable name. R-value is a value of an expression.

But I don't know the details why postfix ++ is not a L-value in C and C++, and why prefix ++ is not in C. (I saw something like "postfix ++...store...in a temporary address, then...", but I still don't get it).

And another question is that why prefix ++ is different in C and C++? Making prefix ++ a L-value (in C++) has many advantages? If so, why C doesn't change this? (Other reasons than backward compatibility, or at least why changing it will cause a lot of problems).

like image 815
user565739 Avatar asked Nov 10 '22 14:11

user565739


1 Answers

C and C++ are different languages. C++ has operator overloading and C does not. The ++ operators, whether prefix or postfix, are operators which can be overloaded in C++. C++ also has references and C does not.

In C, ++i and i++ both yield a value which is not an lvalue. This is desirable, as otherwise you could run afoul with undefined behaviour by trying to modify the same scalar within the same sequence-point boundaries.

Food for thought: In C, the comma operator also produces a value which is not an lvalue, so to "drop" lvalueness, you can do:

(0, lvalue)
like image 196
Shao Avatar answered Nov 14 '22 23:11

Shao