6.7. Generalized Lvalues
Compound expressions, conditional expressions and casts are allowed as
lvalues provided their operands are lvalues. This means that you can take
their addresses or store values into them. All these extensions are
deprecated.
Standard C++ allows compound expressions and conditional expressions
as lvalues, and permits casts to reference type, so use of this
extension is not supported for C++ code.
For example, a compound expression can be assigned, provided the last
expression in the sequence is an lvalue. These two expressions are
equivalent:
Similarly, the address of the compound expression can be taken. These two
expressions are equivalent:
A conditional expression is a valid lvalue if its type is not void and the
true and false branches are both valid lvalues. For example, these two
expressions are equivalent:
(a ? b : c) = 5
(a ? b = 5 : (c = 5)) |
A cast is a valid lvalue if its operand is an lvalue. This extension
is deprecated. A simple
assignment whose left-hand side is a cast works by converting the
right-hand side first to the specified type, then to the type of the
inner left-hand side expression. After this is stored, the value is
converted back to the specified type to become the value of the
assignment. Thus, if a has type char *, the following two
expressions are equivalent:
(int)a = 5
(int)(a = (char *)(int)5) |
An assignment-with-arithmetic operation such as += applied to a cast
performs the arithmetic using the type resulting from the cast, and then
continues as in the previous case. Therefore, these two expressions are
equivalent:
(int)a += 5
(int)(a = (char *)(int) ((int)a + 5)) |
You cannot take the address of an lvalue cast, because the use of its
address would not work out coherently. Suppose that &(int)f were
permitted, where f has type float. Then the following
statement would try to store an integer bit-pattern where a floating
point number belongs:
This is quite different from what (int)f = 1 would do--that
would convert 1 to floating point and store it. Rather than cause this
inconsistency, we think it is better to prohibit use of & on a cast.
If you really do want an int * pointer with the address of
f, you can simply write (int *)&f.