What exactly is lvalue & rvalue (old c.l.c. posts are all over the map)?

  • Thread starter Romeo Colacitti
  • Start date
L

Lawrence Kirby

On Sun, 06 Feb 2005 14:08:02 -0800, Luke Wu wrote:

....
Objects can also exist without lvalues . For example,

1)

char *ptr = "Hello";
ptr = NULL;

/* Hereafter the object "Hello" (an array) is lost in our abstract
machine
never to be referred to by an lvalue */

The string literal itself i.e. the "Hello" in the source code is an lvalue.
2)

malloc(100);

/* Hereafter the object allocated (100 bytes) is lost, never to be
referred to by an lvalue */

True, but not very interesting or useful.
So objects and lvalues are different things.

lvalues exist in the source code, objects exist in the execution
environment.

Lawrence
 
L

Lawrence Kirby

sizeof takes more than lvalues, consider...

sizeof(int *)
sizeof('A')
sizeof(33.029e-3LD)

so are types and constants objects too (note, size of directly taking
the objects as input above, not just lvalues that refer to the objects)


here is another example

sizeof("String Literal")

here, size is receiving only a pointer to the first element of the
string ('S'), so its equivalent to: sizeof(char *)

Why do you assume that to start with? Note that while you are using a
string literal here, it is just an example of an array lvalue.
but that's not what we get, sizeof actually returns the size of the
whole string literal

I don't think sizeof fits cleanly with the theory of lvalues/rvalues.

sizeof is unique because it doesn't evaluate its operand (as a value or an
lvalue); all sizeof cares about is the type of the operand. With C99 VLAs
determining the operand type can require a calculation based on runtime
information but it still isn't accessing the value or lvalue of the
operand (and obviously not if the operand is specifically a type).

Lawrence
 
K

Keith Thompson

Romeo Colacitti said:
Chris said:
If you have
int array[1];
then
array[-1] is an example of an lvalue which doesn't refer
to an object. The use of such an lvalue would be undefined behavior.

Again, apparently true in C99, but not (technically) in C89. But
this just means the C89 standard has a defect.

C99 is worse, because as per the said standard almost every expression
that doesn't resolve to an incomplete types or function type is an
LVALUE. So something like 2+3 is an lvalue in C99. I'll just modify
that errant sentence in the C99, it must obviously be a typo (they
forgot to mention that an lvalue "designates an object.")

Alas, it wasn't a typo. In C90, an lvalue is defined as "an
expression (with an object type or an incomplete type other than void)
that designates an object". The flaw in this definition, given
int *ptr;
the expression *ptr may or may not designate an object (it doesn't of
ptr==NULL, for example). So strictly speaking, you can't always
determine whether an expression is an lvalue until runtime, which
clearly was not the intent.

C99 attempted to correct this by dropping the absolute requirement
that an lvalue must designate an object; an lvalue is now "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." Strictly speaking, 42 is an lvalue (it's an
expression with an object type) -- and evaluating it invokes undefined
behavior. Again, this clearly was not the intent.

An lvalue *should* be defined as an expression that *potentially*
designates an object. For example, *ptr is an lvalue regardless of
the value of ptr, and evaluating *ptr invokes undefined behavior if it
doesn't currently designate an object. The expression 42 is not an
lvalue. The problem, I suppose, is expressing this in standardese,
but IMHO correctness is more important than rigor here.
 
K

Kenneth Bull

Keith said:
An lvalue *should* be defined as an expression that *potentially*
designates an object. For example, *ptr is an lvalue regardless of
the value of ptr, and evaluating *ptr invokes undefined behavior if it
doesn't currently designate an object. The expression 42 is not an
lvalue. The problem, I suppose, is expressing this in standardese,
but IMHO correctness is more important than rigor here.

Or they could just list all possible types of lvalues in a short
passage (there aren't many). They would have to define it according to
the final result of expressions (what they evaluate to), which is what
they mean by "expressions" in the current standard anyway.
 
K

Kenneth Bull

Lawrence said:
sizeof is unique because it doesn't evaluate its operand (as a value or an
lvalue); all sizeof cares about is the type of the operand. With C99 VLAs
determining the operand type can require a calculation based on runtime
information but it still isn't accessing the value or lvalue of the
operand (and obviously not if the operand is specifically a type).

Lawrence

Which is why people shouldn't call sizeof an "object context" or
"lvalue context"
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,770
Messages
2,569,583
Members
45,075
Latest member
MakersCBDBloodSupport

Latest Threads

Top