Why don't rvalues have a memor开发者_开发百科y address? Are they not loaded into the RAM when the program executes or does it refer to the values stored in processor registers?
Your question ("Why don't rvalues have a memory address?") is a bit confused. An rvalue is a kind of expression. Expressions don't have addresses: objects have addresses. It would be more correct to ask "why can one not apply the address-of operator to an rvalue expression?"
The answer to that is rather simple: you can only take the address of an object and not all rvalue expressions refer to objects (for example, the expression 42
has a value but does not refer to an object).
Some rvalue expressions do refer to objects, but such objects lack persistence. An object referred to by an rvalue expression is a temporary object and is destroyed at the end of the expression in which it is created. Such objects do indeed have addresses (you can easily discover this by calling a member function on a temporary object; the this
pointer must point to the temporary object and thus the temporary object must have an address).
This is the fundamental difference between lvalue expressions and rvalue expressions. Lvalue expressions refer to objects that have persistence: the object to which an lvalue expression refers persists beyond a single expression.
Think of rvalue
as value of an expression. The value itself doesn't have address. But the objects involve in the expression do have address. You can take address of an object, even be it a temporary object.
Consider this,
const int & i = 10; //ok
Here, 10
is an rvalue, so it appears that &i
is an address of the 10
. No, that is wrong. &i
is an address of the temporary object of type int
, which is created out of the expression 10
. And since the temporary object cannot be bound to non-const reference, I use const
. That means, the following is an error:
int & i = 10; //error
The question mixes two different aspects related to the "specification" and to the "implementation".
The "specification" define some abstract rules that defines how the language behave respect to an abstract machine it works with. Adapt that "abstract machine" to the "real one" under it its a purpose of the compiler (not the language).
What the specification is enforcing is that -by the language stand point- a "storage" (a piece of memory with a proper address) is given only to objects that have a name (for the existence of the scope that name lives) or that are dynamically allocated with an explicit request (new
).
Everything else is "temporary": assign, copy and moves like an object, but is not required to exist in a well defined and stable place. At least, not for the purpose of the language.
Of course, that has to stay (physically) somewhere, so you can -with appropriate casting or conversion- trying to guess a memory address. But the language specification does not grant any consistent behavior if you try to actively use it. That means that different compilers can behave differently, and optimize the better they can respect to the real machine they target.
What do you mean, rvalues do have an address. Ever tried
Type const value& = rvalue;
Type const* address = &value;
Simply take this case
int a = 1 + 2;
1+2 gets resolved to 3.
Ask yourself:
- Is 3 an object?
- Where would 3 be located in memory?
When you need the address of an object, you use &.
If rvalues would be addressable, it means you could declare a pointer to where your computer decided to store 3
int* a = &3;
Does that seem right? :)
精彩评论