Lawrence Kirby <> writes:
[...]
> Dereferencing a pointer can yield an lvalue. However the text of the
> standard looks terminally broken in this respect. I should probably check
> defects.
Yes, the standard's definition of "lvalue" is badly broken.
C90 6.2.2.1 says:
An _lvalue_ is an expression (with an object type or an incomplete
type other than void) that designates an object.
The problem with this definition is that, strictly speaking, you can't
determine at compilation time whether something is an lvalue or not.
Given a declaration
int *ptr;
the expression *ptr designates an object only if current the value of
ptr is non-null. Presumably the intent was that *ptr is an lvalue
regardless of the current value of ptr (and evaluating it invokes
undefined behavior if ptr happens to be null), but the definition
doesn't capture that intent.
C99 6.3.2.1 corrects this problem, but introduces a bigger one:
An _lvalue_ is an expression with an object type or an incomplete
type other than void; if an lvalue does not designate an object
when it is evaluated, the behavior is undefined.
This captures the idea that "*ptr" is an lvalue even if ptr==NULL --
but it also implies that 42 is an lvalue (because it's an expression
with an object type). It no longer says that an lvalue denotes an
object (which is what the concept of "lvalue" is all about), it merely
threatens undefined behavior if it doesn't.
The standard needs to say that an lvalue is an expression that either
denotes an object, or would denote an object if its subexpressions had
the right values. The trick is expressing this in sufficiently
rigorous standardese.
I raised this issue on comp.std.c a few months ago, but the discussion
wasn't productive.
--
Keith Thompson (The_Other_Keith)
kst- <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.