Why it is not an lvalue ?

J

junky_fellow

Consider the following piece of code:

(char *)0x100; /* I know that converting an integer to pointer
type is implementation defined. But forget
this for a moment */
My question is,
Why the above expression is not an lvalue ? It both specifies the
the storage location as well as the type of object ?

When I try to increment it
(char *)0x100++;
I get the error, that it is not an lvalue.
 
K

Keith Thompson

Consider the following piece of code:

(char *)0x100; /* I know that converting an integer to pointer
type is implementation defined. But forget
this for a moment */
My question is,
Why the above expression is not an lvalue ? It both specifies the
the storage location as well as the type of object ?

When I try to increment it
(char *)0x100++;
I get the error, that it is not an lvalue.

The result of a cast is never an lvalue. A cast takes its operand (an
expression) and converts it to the specified type; the result does not
designate an object.

In the example above, you take the expression 0x100 and convert it to
type char*. Do you expect to change the value of 0x100?

If you apply the unary "*" operator to it, the result is an lvalue.
For example:

*(char*)0x100 ++;

In this case, the object being incremented is the char value at
address 0x100.
 
T

Tim Rentsch

Keith Thompson said:
The result of a cast is never an lvalue. A cast takes its operand (an
expression) and converts it to the specified type; the result does not
designate an object.

In the example above, you take the expression 0x100 and convert it to
type char*. Do you expect to change the value of 0x100?

If you apply the unary "*" operator to it, the result is an lvalue.
For example:

*(char*)0x100 ++;

In this case, the object being incremented is the char value at
address 0x100.

Keith must not have gotten enough to eat earlier and be suffering
from low blood sugar. If he had he surely would have written
that the expression in question is parsed as though it were

(char *) (0x100++);

which doesn't work because a constant can't be incremented. To
increment the char at location 0x100, use

(*(char *)0x100) ++;

or

++ *(char *)0x100;

or

*(char *)0x100 += 1;

Incidentally, it's easy to see that (char *)0x100 can't be an
lvalue, because it can't appear on the left side of an assignment
operator. This

(char *)0x100 = 0;

isn't allowed; whereas, this

*(char *)0x100 = 0;

is.
 
R

Richard Bos

Consider the following piece of code:

(char *)0x100; /* I know that converting an integer to pointer
type is implementation defined. But forget
this for a moment */
My question is,
Why the above expression is not an lvalue ? It both specifies the
the storage location as well as the type of object ?

No, it doesn't. It specifies _a_ storage location, but not the location
where (char *)0x100 is stored.
When I try to increment it
(char *)0x100++;
I get the error, that it is not an lvalue.

That's because you're trying to increment what is, essentially, only an
intermediate value. There is nowhere for that value to be written to.

I suspect that your real intent was to increment not the value _of_
(char *)0x100, but the value _at_ (char *)0x100. If so, you need another
level of indirection.

Richard
 
P

pete

Lawrence said:
On Mon, 20 Jun 2005 01:07:35 -0700, Tim Rentsch wrote:

...


Given

const char ch;

ch is an lvalue that can't appear on the left side of an assignment.

Here's my nonrigorous attempt at a new defintion for lvalue:
There are two kinds of lvalues.
1 A primary expression which is the identifier of an object
is an lvalue.
2 An expression which is the result of an indirection operation,
is an lvalue.

An expression which is the result of any of the following
operators, would be an lvalue.
* (indirection operator)
-> (structure/union pointer operator)
[ ] (array subscript operator)
 
T

Tim Rentsch

Lawrence Kirby said:
On Mon, 20 Jun 2005 01:07:35 -0700, Tim Rentsch wrote:

...


Given

const char ch;

ch is an lvalue that can't appear on the left side of an assignment.

Right. I should have said that the other way - if something
isn't an lvalue, it can't go on the left side of an assignment
statement. Sadly there doesn't seem to be a simple means of
identifying lvalues the way assignment does for modifiable
lvalues.
 
L

Lawrence Kirby

On Mon, 20 Jun 2005 01:07:35 -0700, Tim Rentsch wrote:

....
Incidentally, it's easy to see that (char *)0x100 can't be an
lvalue, because it can't appear on the left side of an assignment
operator.

Given

const char ch;

ch is an lvalue that can't appear on the left side of an assignment.

Lawrence
 
J

James McIninch

<posted & mailed>

literals can't be lvalues. It's perfectly logical. What's the sense of:

5++;

.... are you attemptin to say "all number 5's are now 6's"? No. There's no
variable that's being changed...
 
L

Lawrence Kirby

On Mon, 20 Jun 2005 10:07:59 +0000, pete wrote:

....
Here's my nonrigorous attempt at a new defintion for lvalue:

The standard is really merssed up over the definition of lvalue,
but the basic concept is that an lvalue is an expression that
designates an object.
There are two kinds of lvalues.
1 A primary expression which is the identifier of an object
is an lvalue.

A string literal i.e. "..." in the source code is an lvalue.
2 An expression which is the result of an indirection operation,
is an lvalue.

Unless the operand is a pointr to a function or pointer to void.
An expression which is the result of any of the following
operators, would be an lvalue.
* (indirection operator)
-> (structure/union pointer operator)
[ ] (array subscript operator)

Those are all examples of indirection. The structure/union member
selection operator . also produces an lvalue result if its
operand is an lvalue.

Lawrence
 
P

pete

Lawrence said:
On Mon, 20 Jun 2005 10:07:59 +0000, pete wrote:

...
Here's my nonrigorous attempt at a new defintion for lvalue:

The standard is really merssed up over the definition of lvalue,
but the basic concept is that an lvalue is an expression that
designates an object.
There are two kinds of lvalues.
1 A primary expression which is the identifier of an object
is an lvalue.

A string literal i.e. "..." in the source code is an lvalue.
2 An expression which is the result of an indirection operation,
is an lvalue.

Unless the operand is a pointr to a function or pointer to void.
An expression which is the result of any of the following
operators, would be an lvalue.
* (indirection operator)
-> (structure/union pointer operator)
[ ] (array subscript operator)

Those are all examples of indirection. The structure/union member
selection operator . also produces an lvalue result if its
operand is an lvalue.

Thank you.
 

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,767
Messages
2,569,572
Members
45,045
Latest member
DRCM

Latest Threads

Top