Say the object is
class A {
public : void Silly(){
this = 0x12341234;
}
I know I will get compiler error ' "this" is not a lvalue.' But then it is not a temporary either. So what is the hypothetical declaration of "this" ?
Compiler : GCC 4.2 compiler on mac.
For some class X, this
has the type X* this;
, but you're not allowed to assign to it, so even though it doesn't actually have the type X *const this
, it acts almost like it was as far as preventing assignment goes. Officially, it's a prvalue
, which is the same category as something like an integer literal, so trying to assign to it is roughly equivalent to trying to assign a different value to 'a'
or 10
.
Note that in early C++, this
was an lvalue -- assigning to this
was allowed -- you did that to handle the memory allocation for an object, vaguely similar to overloading new
and delete
for the class (which wasn't supported yet at that time).
It is impossible to provide a "declaration" for this
. There's no way to "declare" an rvalue in C++. And this
is an rvalue, as you already know.
Lvalueness and rvalueness are the properties of expressions that produce these values, not the properties of declarations or objects. In that regard, one can even argue that it impossible to declare an lvalue either. You declare an object. Lvalue is what is produced when you use the name of that object as an expression. In that sense both "to declare an rvalue" and "to declare an lvalue" are oxymoron expressions.
Your question also seems to suggest that the properties of "being an lvalue" and "being a temporary" are somehow complementary, i.e. everything is supposedly an lvalue or a temporary. In reality, the property of "being a temporary" has no business being here. All expressions are either lvalues or rvalues. And this
happens to be an rvalue.
Temporaries, on the other hand, can be perceived as rvalues or as lvalues, depending on how you access the temporary.
P.S. Note, BTW, that in C++ (as opposed to C) ordinary functions are lvalues.
For one thing, this
is not a variable - it's a keyword. When used as a rvalue, its type is A *
or A const *
. In modern C++, assigning to this
is prohibited. You cannot take the address of this
, either. In other words, it's not a valid lvalue.
To answer the second part, "why is this
not an lvalue", I'm speculating as to the committee's actual motivation, but advantages include:
this
doesn't make much logical sense, so there's no particular need for it to appear on the left-hand-side of assignments. Making it an rvalue emphasises that this doesn't make much sense by forbidding it, and means that the standard doesn't have to define what happens if you do it.register
-modified automatic variable. It could for example devote a register in non-static member functions to storing this
. If you take a const reference, then unless the use permits cunning optimization it needs to be copied somewhere that has an address, but at least it needn't be the same address if you do it twice in quick succession, as it would need to be if this
were a declared variable.You get a compiler error because this
is a const pointer to the instance of the class of the same type as that class. You can't assign to it although you can use it to change other class members in non-const qualified methods, call methods, and operators. Also note because it's an instance that static methods do not have a this
pointer.
Hypothetical:
class Whatever
{
// your error because this is Whatever* const this;
void DoWhatever(const Whatever& obj) { this = &obj; }
// this is ok
void DoWhatever(const Whatever& obj) { *this = obj; }
// error because this is now: const Whatever* const this;
void DoWhatever(const Whatever& obj) const { *this = obj; }
// error because this doesn't exist in this scope
static void DoWhatever(const Whatever& obj) { *this = obj; }
};
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With