Why is it illegal to take the address of the "this" pointer?
Asked Answered
B

4

19

I try to find address of this pointer, but this code is showing a strange error:

#include <iostream>
using namespace std;
class Base
{
    public:
        void test()
        {
            void *address_of_this =&this;
            cout<<address_of_this<<endl;
        }
};

int main()
{   Base k;
    k.test();

    return 0;
}   //error non-lvalue in unary'&'   

Can you explain this error ?
Also point that what is illegal in taking address of this?

Barter answered 2/2, 2012 at 15:26 Comment(1)
Try adding a space after the = signBookkeeper
S
45

this is a pointer containing the address to the "current object". It is not a variable that is stored somewhere (or could even be changed), it is a special keyword with these properties.

As such, taking its address makes no sense. If you want to know the address of the "current object" you can simply output:

std::cout << this;

or store as

void* a = this;
Sherlynsherm answered 2/2, 2012 at 15:30 Comment(3)
Finally.. the voice of reason.Joappa
In standardese: this is an rvalue (and not of class type), so it doesn't have an address.Heraldry
In Standardese again, this is prvalue - pure-rvalue.Assure
W
9

Quoting the 2003 C++ standard:

5.1 [expr.prim] The keyword this names a pointer to the object for which a nonstatic member function (9.3.2) is invoked. ... The type of the expression is a pointer to the function’s class (9.3.2), ... The expression is an rvalue.

5.3.1 [expr.unary.op] The result of the unary & operator is a pointer to its operand. The operand shall be an lvalue or a qualified_id.

To put it simply, & requires an lvalue. this is an rvalue, not an lvalue, just as the error message indicates.

Window answered 2/2, 2012 at 15:37 Comment(0)
S
1

This is an artificial restriction.

Compiler optimizations aside, this acts as a hidden pointer parameter to member functions. (Yes, it could sit in a register, but so can regular pointer parameters).

There's no reason this couldn't have worked. My best guess is that nobody thought it would be useful, so they made this a prvalue, which essentially prevents taking its address.

Severally answered 10/9, 2023 at 10:26 Comment(6)
That something does not have a persistent address/location for one to take need not be reason enough not to take its address. A vector could get reallocated and .data() does offer its current address .Speculum
@Speculum Ultimately, inability to take addresses of rvalues is an arbitrary language limitation, desiged to prevent you from shooting yourself in the foot. Nothing would stop us from defining & to materialize prvalues into xvalues, which actually exist in memory, and then allowing & to work on xvalues. It would just be hard to use safely, because the resulting pointer would become dangling at the end of the full-expression that produced it. Here's an interesting example: gcc.godbolt.org/z/Mvqvc7836Severally
I don't think that it is computed on the fly. I rather think that the non-static member function takes a reference to the object that it is called upon as a hidden parameter. So it probably is stored in memory/register but handled as an rvalue to not let the programer interfere with it (reassignment, etc.).Stephine
@Stephine Yes, fair enough. I meant it's computed before calling the member function, but then there's no reason to not be able to take its address in the member function. I've rewrote the answer.Severally
@Severally I myself am researching this topic at the moment (privately). There are resources that confirm this idea, like from Microsoft. But then again, this is a compiler-specific statement. I guess the language spec is not as specific about it to allow for different implementations. Unfortunately I think you got to purchase it to read it.Stephine
@Stephine Nobody pays for the standard, since the drafts are freely available, and have no meaningful differences to the real thing. There's the current draft, and you can find snapshots for specific C++__ versions. Don't read too deep into it, trying to account for all the possible weird implementations leads nowhere.Severally
F
0

this refers to the current object by using it's address.

In your problem, there are two errors:

  • this is not an lvalue.

    The & requires an lvalue. lvalues are those that can appear on on the left-hand side of an assignment (variables, arrays, etc.).

    Whereas this is a rvalue. rvalues can not appear on the left-hand side (addition, subtraction, etc.).

    Reference: C++ Rvalue References Explained.

  • A hidden error which I'd like to also mention is thus:

    address_of_this is actually receiving an address of an address.

    Basically, &this is translated into something like &&object or &(&object).

Basically, think of this as &object (but only to remember because it is not that true).

Fascinate answered 23/6, 2018 at 14:9 Comment(1)
It isn't very clear, what you wanna imply in your 2nd error.Lanny

© 2022 - 2024 — McMap. All rights reserved.