How to get the pointer of "this" ?

Steven Schveighoffer schveiguy at gmail.com
Tue May 26 14:42:04 UTC 2020


On 5/26/20 8:08 AM, Johannes Loher wrote:
> On Tuesday, 26 May 2020 at 11:44:58 UTC, Vinod K Chandran wrote:
>> On Monday, 25 May 2020 at 16:39:30 UTC, Mike Parker wrote:
>>> On Monday, 25 May 2020 at 08:39:23 UTC, John Burton wrote:
>>>
>>>> I believe that in D *this* is a reference to the
>>>> object and not a pointer like in C++.
>>>> So I think that writing &this might be what you need?
>>>
>>> No. A class reference is a pointer under the hood. Getting its 
>>> address will result in a pointer to the reference variable itself, 
>>> not to the class instance. When passing a reference to a C API, 
>>> casting it directly to the C type is correct.
>>
>> Try this code. This will reproduce the same error.
>> import std.stdio : log = writeln;
> 
>> void main() {
>>      log("Let's check whether 'this' is an lvalue or not.");
>>      Button btn = new Button("A button");
>> }
>>
>> class Button {
>>     this(string btntext)    {
>>         mtext = btntext;
>>         log("button created with the name , ", btntext);
>>         log(&this);
>>     }
>>     private:
>>     string mt
>> }
> It doesn't compile, the line
> 
> string mt
> 
> should be
> 
> string mtext;
> 
> instead. Indeed, we get a compiler error:
> 
> Error: this is not an lvalue and cannot be modified.
> 
> The problem is in line 11: You are trying to get the address of `this`. 
> But `this` is an lvalue, so it does not have an address you could take. 
> It becomes mir clear that this doesn’t work if you consider other 
> lvalues, like literals:
> 
> int* = &1; // doesn’t compile, can’t take the address of an lvalue.
> 
> In this code example, the correct thing to do is to simply not take the 
> address but pass `this` to `writeln`. That compiles and results in the 
> following output:
> 
> Let's check whether 'this' is an lvalue or not.
> button created with the name , A button
> onlineapp.Button
> 
> (The module is onlineapp because I ran it in run.dlang.io)
> 
> I don't know what the correct thing would be in your original code though.
> 


Hm... According to run.dlang.io, this behavior changed in 2.072 (prior 
to that it worked). In  2.067.1 to 2.071.2, changing the this reference 
was actually allowed, but deprecated.

Technically, you don't need to do this. Passing an address to a class 
reference isn't going to benefit anything, as a class reference already 
is a pointer. This is, of course, unless you want to CHANGE the class 
reference. Which is disallowed for `this`.

Technically speaking, `this` is simply a local parameter. It technically 
could be changed, but it is not allowed because of the bad code that 
would likely result.

-Steve


More information about the Digitalmars-d-learn mailing list