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).
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)
It is true that
pre increment/decrement operator (++var or --var) yields an lvalue (i.e a modifiable object)
post increment/decrement operator (var++ or var--) yields an rvalue (i.e a temporary object).
Consider following code with pre increment/decrement operator
{
int i = 0;
int* pi = &(++i);
}
It´s OK because in fact its pseudo code is
i = i+1; // pre increment i
int* pi = &i; // then evaluate its address and assign it to pi
Now consider the same code but with post increment/decrement operator and its consequences if it was accepted by the compiler
{
int i = 0;
int* pi = &(i++); // Not OK !! because virtually it is a temporary variable
}
Its pseudo code would be
int i = 0;
int tmp = i; // compiler creates a temporary variable to save value of i
int* pi = &tmp; // then would take the address of a temporary variable
i = i + 1; // the post increment happening only after the assignment !!!
I hope this help clarifying a bit ;)
来源:https://stackoverflow.com/questions/21351799/postfix-prefix-increment-l-value-and-r-value-in-c-and-c