May 26, 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
May 26, 2020
On Tuesday, 26 May 2020 at 13:37:22 UTC, Vinod K Chandran wrote:
> On Tuesday, 26 May 2020 at 12:41:20 UTC, John Chapman wrote:
>> On Monday, 25 May 2020 at 16:26:31 UTC, Vinod K Chandran wrote:
>>> Here is my full code. Please take a look.
>>> https://pastebin.com/av3nrvtT
>>
>> Change line 124 to:
>>
>> SetWindowSubclass(this.mHandle, SUBCLASSPROC(&btnWndProc), UINT_PTR(subClsID), cast(DWORD_PTR)cast(void*)this);
>>
>> That is, change `&this` to `cast(void*)this`.
>
> Hi,
> Thanks for the reply. That will work like charm but we need to change the code in subclassed button's WndProc  like this--
> extern(Windows)
> private LRESULT btnWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam, UINT_PTR scID, DWORD_PTR refData) {
>     try  {
>
>         Button thisBtn = cast(Button)cast(void*)refData;
>      {
>     catch (Exception e) {}
>     ....

Yes, that should work.
May 26, 2020
On Tuesday, 26 May 2020 at 14:42:04 UTC, Steven Schveighoffer wrote:
On Tuesday, 26 May 2020 at 14:42:04 UTC, Steven Schveighoffer wrote:
>
>
> 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

Hi,
Thanks for the reply. I've got the point.
May 26, 2020
On Tuesday, 26 May 2020 at 12:08:29 UTC, 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.
You can just do this to get around it:

         auto button = this;
         log(&button);

May 27, 2020
On Tuesday, 26 May 2020 at 22:23:19 UTC, bauss wrote:
> On Tuesday, 26 May 2020 at 12:08:29 UTC, Johannes Loher wrote:
>> [...]
> You can just do this to get around it:
>
>          auto button = this;
>          log(&button);

True, somebody else posted the same idea already. But as explained, it doesn't do the correct thing.
1 2 3 4
Next ›   Last »