Alf P. Steinbach wrote:
[color=blue]
> * "Steven T. Hatton" <susudata@setidava.kushan.aa> schriebt:[color=green]
>>
>> As I understand the distinction between rvalue and lvalue, an lvalue
>> *can* appear on the left side of an expression, whereas an rvalue can
>> *only* appear on the right side.[/color]
>
> If they're not part of expressions.
>
> Another more useful difference is that you can take the address of an
> lvalue, but not of an rvalue.
>
> An lvalue denotes a storage location, an rvalue denotes a value sans
> location, such as the int value 5.[/color]
If I have a literal 5 in my source code it begins life as an ascii
character. That is translated and used by the compiler. It is either
consumed to produce a result that somehow makes its way into the runtime
instance of the program, or it is directly inserted into the runtime. E.g.,
const int x = 5 * 125; // 5 is consumed and forgotten
const int y = 5; // 5 lives a long and significant life
int f(const int& n){
return 5 * n; // 5 has to stick around in the shadows somewhere
}
[color=blue]
> Thus, an rvalue cannot by itself appear on the left hand side in an
> assignment, and that's the basis of the terminology.
>
> But the terminology is a bit misleading: a const lvalue can't appear on
> the left hand side of an assignment, either (although what's there must be
> an lvalue).[/color]
I guess some of the difficulty is that we are talking about two drastically
different models of the same abstract problem space. One is the text-based
source code, the other is the runtime representation of the program in
storage. When I read your statement that const lvalue can't appear on the
lefthand side of an assignment I thought I understood and agreed with it.
Then I wrote the two examples above. Does this mean that x and y only
become const lvalues after they are initialized (defined)?
I will grant that I know of no way to specify the location of 5 in the
functon f above, but it has to have some kind of representaton in runtime
storage. I'm not sure if it would be categorize as an rvalue. I'm just
using it to try to get an undstanding of what parts of the source code find
their way into the runtime image, and how they are represented there.
I believe I undstood this stuff about ten years ago.
[color=blue]
>[color=green]
>> What I don't fully understand is
>>
>> 1) who cares? What I mean to ask is, why is it so important to specify?[/color]
>
> A program that modified the value of 5, say, would be difficult to debug.[/color]
Agreed. But I knew that before I knew it was called an rvalue.
[color=blue][color=green]
>> I assume it's a way of defining the syntax rules by specifying that
>> lvalues
>> can go here, but not rvalues, etc. But this seems like the chicken and
>> the
>> egg almost. There is talk of lvalue to rvalue conversion in 4.1. Is that
>> just a conceptual artifice, or something the compiler actually does?[/color]
>
> I think it's your job to quote the relevant passage in 4.1.[/color]
This is a better link than the one I posted previously in this thread:
http://www.itga.com.au/~gnb/wp/cd2/
4.1 Lvalue-to-rvalue conversion [conv.lval]
1 An lvalue (_basic.lval_) of a non-function, non-array type T can be
converted to an rvalue. If T is an incomplete type, a program that
necessitates this conversion is ill-formed. If the object to which
the lvalue refers is not an object of type T and is not an object of a
type derived from T, or if the object is uninitialized, a program that
necessitates this conversion has undefined behavior. If T is a non-
class type, the type of the rvalue is the cv-unqualified version of T.
Otherwise, the type of the rvalue is T. 1)
2 The value contained in the object indicated by the lvalue is the
rvalue result. When an lvalue-to-rvalue conversion occurs within the
operand of sizeof (_expr.sizeof_) the value contained in the refer-
enced object is not accessed, since that operator does not evaluate
its operand.
[color=blue]
> Converting an lvalue to rvalue is often necessary. E.g. you can use an
> int
> variable wherever you can use an int value such as 5. The opposite
> conversion is of course not allowed; e.g. you cannot assign to the value
> 5.[/color]
But to say an lvalue is converted to an rvalue doesn't mean much to me.
Does something actually happen in the CPU to change the representation of
the object? Also, if the rvalue /is/ an object, it has a storage location
doesn't it?
[color=blue][color=green]
>> 2) I'm not sure why a function or a string literal would be considered an
>> lvalue.[/color]
>
> Function: because you must be able to take its address in order to use
> function pointers.
>
> String literal: because early C did not have 'const', and so old C
> functions that take 'char*' as argument could not be called with literal
> strings as
> actual arguments if string literals were considered rvalues. However,
> that
> may still change. It's just an old compatibility feature on its way out.[/color]
There's something I'm missing here. What is the difference in how the
program represents and process the same object as an rvalue or an lvalue?
--
STH
Hatton's Law: "There is only One inviolable Law"
KDevelop:
http://www.kdevelop.org SuSE:
http://www.suse.com
Mozilla:
http://www.mozilla.org