K
Keith Thompson
Isn't that addition redundant? I can't think of *any* context where an
lvalue that doesn't desginate an object can be safely evaluated.
Yes, you're right. (I get the feeling this isn't the first time I've
made that mistake.)
The current standard says (C99 6.3.2.1p1):
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.
The second part of the sentence is ok. For example:
int i;
int *ptr = NULL;
i = *ptr;
*ptr is an lvalue, it's being evaluated in a context that doesn't
require an lvalue, and the behavior is undefined because it doesn't
currently designate an object. <OT>(I think the way C++ expresses it
is that it's evaluated as an lvalue, and then an lvalue-to-rvalue
conversion is performed.)</OT>
The real problem is that the first part of the sentence is too broad;
it makes 42 an lvalue, which it clearly is not intended to be.
The C90 standard's definition (an lvalue is an expression ... that
designates an object) was too narrow; it implied that *ptr is an
lvalue if and only if ptr currently contains a valid non-null pointer
value, whereas lvalue-ness needs to be determinable at compile time.
Either an lvalue needs to be defined as an expression that
*potentially* designates an object (defining "potentially" is tricky),
or the definition needs to enumerate the set of expressions that are
lvalues (I think they can be defined syntactically), or it can just
say that an lvalue is an expression whose description in section 6.5
says it's an lvalue.