[...]
Im not sure I follow, an rvalue is the value of an expression, its not
an expression? While an lvalue is an expression?
Yes, given the way the C standard defines the terms.
But an lvalue is an
expression that does not evaluate to an rvalue?
No.
Keep in mind that the C standard doesn't generally use the term
"rvalue". The only two occurences of the term are in that footnote
and in the corresponding index entry. If you're discussing C, it's
best to avoid the term "rvalue" altogether.
If an lvalue (a kind of expression) appears in a context that requires
an lvalue, it doesn't yield a result in the ordinary sense; rather, it
serves to designate (or identify) the object that's required in that
context. If it appears on the LHS of an assignment operator, it
designates the object to which a value is to be assigned. If it
appears as the operand of a unary "&" operator, it designates the
object whose address is taken. And so forth.
If an lvalue appears in a context that *doesn't* require an lvalue, it
yields an ordinary value -- specifically, it yields the stored value
of the object that it designates.
Thus:
int x = 10;
int y = 20;
x = y;
In the assignment, both ``x'' and ''y'' are lvalues. Since ``x'' is
in a context that requires an lvalue, it identifies the object to be
written to (the previous value of that object, 10, is ignored). Since
''y'' is in a context that *doesn't* require an lvalue, it yields the
value (20) stored in the object that it designates (y).
(I'm using ``y'' to refer to the expression consisting of the
identifier y and just y to refer to the object. This isn't a standard
typographical convention, just the one I'm using here.)
And since an lvalue is
an expression it evaluates to something, what exactly does it evaluate
to?
It depends on the context; see above.
Something that has a designated object and has a type? I read that
PDF and it said: "if an lvalue does not designate an object when it is
evaluated..." so it is something that designates an object? Am I
thinking wrong?
An lvalue is an expression that designates an object.
Actually, that's not *quite* accurate. Given:
int *ptr = NULL;
the expression *ptr is an lvalue, even though it doesn't happen to
refer to any object at run time. This is the subtlety that has
tripped up the authors of the standard in trying to define the term.
(I won't go into the gory details yet again unless you really want me
to.)
What the standard probably should say is "if an lvalue does not
designate an object when it is evaluated *in a context that requires
an lvalue*, the behavior is undefined. And the definition should say
something along the lines that an lvalue is an expression that
*potentially* designates an object.
Given:
int x = 42;
int *ptr;
the expressions ``x'' and` ``*ptr'' are both lvalues. ``x''
unconditionally designates an object. ``*ptr'' may or may not
designate an object, depending on the value currently stored in
ptr; this is where the potential for undefined behavior comes in.
``42'' cannot possibly designate an object and is not an lvalue,
so an attempt to use it in a context requiring an lvalue will be
flagged at compile time.
And the expression does evaluate to an address?
No. Evaluating an lvalue in a context that requires an lvalue
identifies an object. It doesn't yield the object's address. It
could well be implemented by computing the object's address, but
consider this:
register int reg;
reg = 42;
The object reg has no address, but ``reg'' nevertheless designates
that object. The same applies to bit fields, which also have no
address.
I read
this:
http://accu.org/index.php/journals/227it sorta says "every
expression yields either an lvalue or an rvalue and accordingly every
expression is called either an lvalue or an rvalue expression." that
is wrong, well it appears to be right now anyhow?
It "sorta says"? Actually, you quoted the exact words, but you
didn't quote the beginning of the sentence:
*In C++* every expression yields either an lvalue or an rvalue and
accordingly every expression is called either an lvalue or an
rvalue expression.
I think that C++ defines the terms differently than C does. For
information on C++, see elsewhere.
I mentioned that the C standard doesn't use the traditional meanings
of the terms. I'll summarize my understanding of what those
traditional meanings are.
In a very simple language without objects, each expression yields a
value when evaluated. ``2 + 2'' yields the value 4, for example.
Once you introduce objects, assuming you want to treat assignments as
expressions, there are two possible ways to evaluate an expression.
You can either evaluate it to determine its value (``2 + 2'' yields
4, ``x + 3'' yields 45 if you've previously stored the value 42 in
x) *or* you can evaluate it to determine what object it designates,
ignoring any value that might be stored in that object. Which of
these things happens depends on the context in which the expression
appears. Traditionally, the former is referred to as "evaluating
an expression for its rvalue", and the latter as "evaluating an
expression for its lvalue". An rvalue is just an ordinary value of
some type. An lvalue is something that, rather than being a *value*
of some type, identifies an *object* of some type. The traditional
terminology unifies these two things (having a value vs. identifying
an object) into the single concept of "value", divided into "rvalue"
and "lvalue". The names of course come from the contexts in which
they appear, the right side vs. the left side of an assignment.
Note that some expressions, such as ``2 + 2'' cannot be evaluated for
their lvalues. (In C terms, ``2 + 2'' is not an lvalue.)
The authors of the C standard chose to drop the concept of "rvalue"
(other than a brief mention in a footnote which matches the
traditional meaning) and redefine "lvalue" as a kind of expression
rather than as the result of evaluating such an expression.
I'm sorry this is so long; I didn't have time to make it shorter.
--
Keith Thompson (The_Other_Keith) (e-mail address removed) <
http://www.ghoti.net/~kst>
Nokia
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"