Re: How to get the pointer of "this" ?
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(); True, somebody else posted the same idea already. But as explained, it doesn't do the correct thing.
Re: How to get the pointer of "this" ?
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 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(); } 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();
Re: How to get the pointer of "this" ?
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.
Re: How to get the pointer of "this" ?
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(), UINT_PTR(subClsID), cast(DWORD_PTR)cast(void*)this); That is, change `` 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.
Re: How to get the pointer of "this" ?
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 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(); } 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
Re: How to get the pointer of "this" ?
Am 26.05.20 um 16:17 schrieb Vinod K Chandran: > On Tuesday, 26 May 2020 at 13:48:52 UTC, ag0aep6g wrote: >> On 26.05.20 15:43, Vinod K Chandran wrote: >>> So far now, two solutions are very clear for this problem. >>> 1. As per John Chapman's suggestion - use >>> cast(DWORD_PTR)cast(void*)this). >>> 2. Use another varibale to use as an lvalue. - >>> Button dummyBtn = this; >>> cast(DWORD_PTR) >>> Among these two, i think 2nd option is good. Am i right ? >> >> No. Use option 1. > > Could you please tell me why ? With option 2, you will not actually get a pointer to the object but a pointer to the local variable which is a reference to the object. `this` and the local variable both are references to the object, so internally they already are pointers. Their usage is just restricted in regular D code. This is also why simply casting it to a pointer works. You need to cast to void* in between because that's just the way to tell the compiler to ignore the restrictions you usually have for references.
Re: How to get the pointer of "this" ?
On Tuesday, 26 May 2020 at 13:48:52 UTC, ag0aep6g wrote: On 26.05.20 15:43, Vinod K Chandran wrote: So far now, two solutions are very clear for this problem. 1. As per John Chapman's suggestion - use cast(DWORD_PTR)cast(void*)this). 2. Use another varibale to use as an lvalue. - Button dummyBtn = this; cast(DWORD_PTR) Among these two, i think 2nd option is good. Am i right ? No. Use option 1. Could you please tell me why ?
Re: How to get the pointer of "this" ?
On Tuesday, 26 May 2020 at 13:44:24 UTC, Adam D. Ruppe wrote: On Tuesday, 26 May 2020 at 11:35:23 UTC, Vinod K Chandran wrote: Okay, but uint is working perfectly. It won't if you use -m64. Okay. I got it.
Re: How to get the pointer of "this" ?
On 26.05.20 15:43, Vinod K Chandran wrote: So far now, two solutions are very clear for this problem. 1. As per John Chapman's suggestion - use cast(DWORD_PTR)cast(void*)this). 2. Use another varibale to use as an lvalue. - Button dummyBtn = this; cast(DWORD_PTR) Among these two, i think 2nd option is good. Am i right ? No. Use option 1.
Re: How to get the pointer of "this" ?
On Tuesday, 26 May 2020 at 11:35:23 UTC, Vinod K Chandran wrote: Okay, but uint is working perfectly. It won't if you use -m64.
Re: How to get the pointer of "this" ?
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(), UINT_PTR(subClsID), cast(DWORD_PTR)cast(void*)this); That is, change `` 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) {} So far now, two solutions are very clear for this problem. 1. As per John Chapman's suggestion - use cast(DWORD_PTR)cast(void*)this). 2. Use another varibale to use as an lvalue. - Button dummyBtn = this; cast(DWORD_PTR) Among these two, i think 2nd option is good. Am i right ?
Re: How to get the pointer of "this" ?
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: [...] [...] It doesn't compile, the line string mt [...] Hi, Sorry for the typos in my code.
Re: How to get the pointer of "this" ?
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(), UINT_PTR(subClsID), cast(DWORD_PTR)cast(void*)this); That is, change `` 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) {}
Re: How to get the pointer of "this" ?
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(), UINT_PTR(subClsID), cast(DWORD_PTR)cast(void*)this); That is, change `` to `cast(void*)this`.
Re: How to get the pointer of "this" ?
On Tuesday, 26 May 2020 at 12:08:29 UTC, Johannes Loher wrote: [...] Small correction: I said that this is an lvalue and that you cannot take the address of lvalues. Of course that is incorrect, I meant to say that rvalues (this is an rvalue and you cannot take the address of rvalues).
Re: How to get the pointer of "this" ?
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 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(); } 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.
Re: How to get the pointer of "this" ?
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 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(); } private: string mt }
Re: How to get the pointer of "this" ?
On Monday, 25 May 2020 at 18:42:33 UTC, bauss wrote: On Monday, 25 May 2020 at 17:14:13 UTC, Vinod K Chandran wrote: On Monday, 25 May 2020 at 16:54:11 UTC, Mike Parker wrote: [...] Hi @Mike Parker, Thank you for your valuable suggestions. I will sure follow them. Well, the exact line number where the error showing is the one with the "SetWindowSubclass" function. In pastebin, the line number is 124. Need to see the Control class too. I think the problem might be something you're referencing from there but need to be sure. Here is some code to reproduce the error in your system. https://pastebin.com/rgN3ug1e 'this' is not an lvalue.
Re: How to get the pointer of "this" ?
On Monday, 25 May 2020 at 22:54:32 UTC, Adam D. Ruppe wrote: On Monday, 25 May 2020 at 22:31:00 UTC, Vinod K Chandran wrote: A dword is an unsigned, 32-bit unit of data. We can use uint in D. I have tried that too, but no luck. A DWORD_PTR is *not* the same as a uint. It is more like a size_t or void* depending on context. Okay, but uint is working perfectly.
Re: How to get the pointer of "this" ?
On Monday, 25 May 2020 at 22:32:52 UTC, Vinod K Chandran wrote: What is an opCast ? operator overload of the cast function. if you didn't write one, you don't have to worry about this.
Re: How to get the pointer of "this" ?
On Monday, 25 May 2020 at 22:31:00 UTC, Vinod K Chandran wrote: A dword is an unsigned, 32-bit unit of data. We can use uint in D. I have tried that too, but no luck. A DWORD_PTR is *not* the same as a uint. It is more like a size_t or void* depending on context.
Re: How to get the pointer of "this" ?
On Monday, 25 May 2020 at 22:04:28 UTC, Adam D. Ruppe wrote: On Monday, 25 May 2020 at 21:45:39 UTC, welkam wrote: Where is DWORD_PTR defined? it is a win32 thing. should be able to directly cast to it most the time if there is opCast on the class it needs another layer of helper function but without opCast it should just work Hi, What is an opCast ?
Re: How to get the pointer of "this" ?
On Monday, 25 May 2020 at 21:45:39 UTC, welkam wrote: On Sunday, 24 May 2020 at 17:05:16 UTC, Vinod K Chandran wrote: cast(DWORD_PTR) this); Where is DWORD_PTR defined? I cant find it in docs. If its an alias of long then you have to cast to a pointer like this cast(long*) this; you need to specify that you want to cast to a pointer of type T. In this case T is long. Hi, Thanks for the reply. Well, DWORD_PTR is a win32 data type. It is defined in the file windows.h. A dword is an unsigned, 32-bit unit of data. We can use uint in D. I have tried that too, but no luck.
Re: How to get the pointer of "this" ?
On Monday, 25 May 2020 at 21:45:39 UTC, welkam wrote: Where is DWORD_PTR defined? it is a win32 thing. should be able to directly cast to it most the time if there is opCast on the class it needs another layer of helper function but without opCast it should just work
Re: How to get the pointer of "this" ?
On Sunday, 24 May 2020 at 17:05:16 UTC, Vinod K Chandran wrote: cast(DWORD_PTR) this); Where is DWORD_PTR defined? I cant find it in docs. If its an alias of long then you have to cast to a pointer like this cast(long*) this; you need to specify that you want to cast to a pointer of type T. In this case T is long.
Re: How to get the pointer of "this" ?
On Monday, 25 May 2020 at 18:42:33 UTC, bauss wrote: On Monday, 25 May 2020 at 17:14:13 UTC, Vinod K Chandran wrote: On Monday, 25 May 2020 at 16:54:11 UTC, Mike Parker wrote: [...] Hi @Mike Parker, Thank you for your valuable suggestions. I will sure follow them. Well, the exact line number where the error showing is the one with the "SetWindowSubclass" function. In pastebin, the line number is 124. Need to see the Control class too. I think the problem might be something you're referencing from there but need to be sure. @bauss, Here is the code for Control class. https://pastebin.com/Hy9dCNdS
Re: How to get the pointer of "this" ?
On Monday, 25 May 2020 at 17:14:13 UTC, Vinod K Chandran wrote: On Monday, 25 May 2020 at 16:54:11 UTC, Mike Parker wrote: On Monday, 25 May 2020 at 16:26:31 UTC, Vinod K Chandran wrote: [...] The error has nothing to do with taking a pointer to `this`. It's suggesting that somewhere in your code you're attempting to use the `this` reference like an lvalue, e.g. making an assignment to it. I don't see anywhere that you're doing that. Glancing through the code, I don't see anywhere that you're doing that (and unfortunately this is not a minimal example because of dependencies on some of your other modules, so I can't compile it myself). [...] Hi @Mike Parker, Thank you for your valuable suggestions. I will sure follow them. Well, the exact line number where the error showing is the one with the "SetWindowSubclass" function. In pastebin, the line number is 124. Need to see the Control class too. I think the problem might be something you're referencing from there but need to be sure.
Re: How to get the pointer of "this" ?
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 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. Ah I see. In that case I have some code I need to investigate as it's probably only working by accident!
Re: How to get the pointer of "this" ?
On Monday, 25 May 2020 at 16:54:11 UTC, Mike Parker wrote: On Monday, 25 May 2020 at 16:26:31 UTC, Vinod K Chandran wrote: [...] The error has nothing to do with taking a pointer to `this`. It's suggesting that somewhere in your code you're attempting to use the `this` reference like an lvalue, e.g. making an assignment to it. I don't see anywhere that you're doing that. Glancing through the code, I don't see anywhere that you're doing that (and unfortunately this is not a minimal example because of dependencies on some of your other modules, so I can't compile it myself). [...] Hi @Mike Parker, Thank you for your valuable suggestions. I will sure follow them. Well, the exact line number where the error showing is the one with the "SetWindowSubclass" function. In pastebin, the line number is 124.
Re: How to get the pointer of "this" ?
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 The error has nothing to do with taking a pointer to `this`. It's suggesting that somewhere in your code you're attempting to use the `this` reference like an lvalue, e.g. making an assignment to it. I don't see anywhere that you're doing that. Glancing through the code, I don't see anywhere that you're doing that (and unfortunately this is not a minimal example because of dependencies on some of your other modules, so I can't compile it myself). What was the line number of the original error? Sometimes the line number reported isn't where the error actually occurs. Also, try to see if you can minimize it so that someone else can compile it. A couple of points about your code unrelated to your error: * `private static int btnNumber = 1;` -- `static` has no meaning at module scope. You'll see it in C code, but in D `private` provides the same functionality. You can delete `static` from those module scope declarations. * `with(this){` -- you absolutely do not need to do this. `this` is never required as a prefix on any member unless, e.g., a member variable and another more locally scoped variable have the same name, like `this.x = x` in a setter function to distinguish the member variable from the function parameter. You're already using the convention of naming your member variables with a `m` prefix, so you won't run into that issue. `this.mFoo` is exactly the same as `mFoo`, and with(this) is pointless. I mean, if you want to use `this.mFoo` as a stylistic choice, that's your call (though the `m` makes it redundant really), but even then using `with(this)` serves no purpose.
Re: How to get the pointer of "this" ?
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 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.
Re: How to get the pointer of "this" ?
On Sunday, 24 May 2020 at 17:40:10 UTC, bauss wrote: On Sunday, 24 May 2020 at 17:05:16 UTC, Vinod K Chandran wrote: [...] I think your issue might be elsewhere because casting this should be fine and it should not complain about that in your given code. At least you should be able to pass this to another function or even cast it. Please show the full code and the full error which gives you the stacktrace of where it's called and from where. Here is my full code. Please take a look. https://pastebin.com/av3nrvtT
Re: How to get the pointer of "this" ?
On Sunday, 24 May 2020 at 17:40:10 UTC, bauss wrote: On Sunday, 24 May 2020 at 17:05:16 UTC, Vinod K Chandran wrote: [...] I think your issue might be elsewhere because casting this should be fine and it should not complain about that in your given code. At least you should be able to pass this to another function or even cast it. Please show the full code and the full error which gives you the stacktrace of where it's called and from where. I believe that in D *this* is a reference to the object and not a pointer like in C++. So I think that writing might be what you need?
Re: How to get the pointer of "this" ?
On Sunday, 24 May 2020 at 17:05:16 UTC, Vinod K Chandran wrote: Hi all, I have a class like this. class Button : Control { ... HWND createButton(){ ... SetWindowSubclass(this.mHandle, SUBCLASSPROC(), UINT_PTR(subClsID), cast(DWORD_PTR) this); } } But compiler says that - "Error: 'this' is not an lvalue and cannot be modified" I've seen many cpp code which uses pointer to 'this' as the last parameter in SetWindowSubclass(). Is there something wrong with my approach ? I think your issue might be elsewhere because casting this should be fine and it should not complain about that in your given code. At least you should be able to pass this to another function or even cast it. Please show the full code and the full error which gives you the stacktrace of where it's called and from where.