Dereferencing a pointer can yield an lvalue.
[snip]
And when it doesn't?
Essentially the problem is that the concept of lvalue is used in
constraint specifications (e.g. 6.5.16p2) which means that it is a
property that must be determinable at compile time, i.e. from static
analysis of the source code. C99 6.5.3.2p4 says
"The unary * operator denotes indirection. If the operand points to a
function, the result is a function designator; if it points to an object,
the result is an lvalue designating the object."
This is a specification for lvalue-ness based on a runtime property i.e.
whether the pointer points at an object or not, which makes it unworkable.
I understand your point. However, on second thought, this is not a
definition. What is says is that `*p' 1. designates the object `p'
points to (and not some other), and 2. is an lvalue (the expression can
potentially exist in any position where an lvalue is expected).
If `p' does not point to any valid object, `*p' raises UB (because
the Standard fails to define it); past this point there is no need to
consider whether `*p' is an lvalue or not, the behaviour is undefined
anyway. (The case of &*p has been covered in earlier section.)
"An lvalue is an expression with an object type or an incomplete type
other than void;"
This is the definition. Lvalue is compile-time concept.
Note specifically that lvalues can have an incomplete type which is good
and correct. This of course has its own problems, apparently saying that
the expression 42 is an lvalue.
I wrote this because my idea of lvalue was not the same as in the
Standard. Thanks for pointing this out to me (I also thank Keith
Thompson for his post). I start to feel that the concept of lvalue
is not only semantical (object designator), but also it is a "label"
that takes part in grammatical analysis of expressions; maybe this is
the reason why certain rules seem a little confusing.
I think I need to stop right here and think things over again, I really
can't add anything productive at this point. Discussing with you has
been very enlightening for me, thanks a lot!
struct mystruct *p;
*p; //gcc refused to compile
The last sentence in 6.3.2.1p2 (incredible how I selectively read that
text) says, referring to lvalues not being an operand to unary & and
other operators:
# If the lvalue has an incomplete type and does not have array type,
# the behavior is undefined.
which covers my previous question. However, I wouldn't like a compiler
that would issue only a warning.