www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Voldemort type "this" pointer

reply realhet <real_het hotmail.com> writes:
Hi,

I noticed that there is a hidden "this" pointer in a struct that 
I declare inside a body of a function.
Also noticed when I use the "static" keyword, the "this" pointer 
disappears.

My question is about what is the "this" pointer for. Is it for 
storing the stack frame of the function in order to be able to 
serve queries that can lazily use the data from the stack frame?

(I guess it's something else because that part of the stack might 
be undefined after exiting from the function.)
Apr 21 2021
parent reply Mike Parker <aldacron gmail.com> writes:
On Wednesday, 21 April 2021 at 10:00:51 UTC, realhet wrote:

 My question is about what is the "this" pointer for. Is it for 
 storing the stack frame of the function in order to be able to 
 serve queries that can lazily use the data from the stack frame?

 (I guess it's something else because that part of the stack 
 might be undefined after exiting from the function.)
From the documentation
 1. A nested struct is a struct that is declared inside the 
 scope of a function or a templated struct that has aliases to 
 local functions as a template argument. Nested structs have 
 member functions. It has access to the context of its enclosing 
 scope (via an added hidden field).
 2. A struct can be prevented from being nested by using the 
 static attribute, but then of course it will not be able to 
 access variables from its enclosing scope.
https://dlang.org/spec/struct.html#nested
Apr 21 2021
parent reply realhet <real_het hotmail.com> writes:
On Wednesday, 21 April 2021 at 10:47:08 UTC, Mike Parker wrote:
 On Wednesday, 21 April 2021 at 10:00:51 UTC, realhet wrote:

 It has access to the context of its enclosing scope (via an 
 added hidden field).
Thanks! So it is unsafe to return a non-static nested struct from a function. But it is useful to pass it forward into other functions.
Apr 21 2021
parent reply =?UTF-8?Q?Ali_=c3=87ehreli?= <acehreli yahoo.com> writes:
On 4/21/21 8:37 AM, realhet wrote:
 On Wednesday, 21 April 2021 at 10:47:08 UTC, Mike Parker wrote:
 On Wednesday, 21 April 2021 at 10:00:51 UTC, realhet wrote:

 It has access to the context of its enclosing scope (via an added 
 hidden field).
Thanks! So it is unsafe to return a non-static nested struct from a function. But it is useful to pass it forward into other functions.
Not at all. (D is good at preventing such bugs anyway.) The local context that the nested struct object uses becomes the context of that object. Here is a poor person's proof (one can inspect the assembly output to observe delegate allocation as well): import std.stdio; auto foo() { int i; writeln(&i, " <- dynamic memory inside foo"); struct S { void bar() { writeln(&i, " <- dynamic memory inside bar"); } } return S(); } void main() { int m; writeln(&m, " <- stack address inside main"); auto s = foo(); s.bar(); } Sample output strongly suggests 'i' is not on the stack because the addresses are distant: 7FFFC14D85C0 <- stack address inside main 7FF424B9C008 <- dynamic memory inside foo 7FF424B9C008 <- dynamic memory inside bar Ali
Apr 21 2021
parent realhet <real_het hotmail.com> writes:
On Wednesday, 21 April 2021 at 15:53:59 UTC, Ali Çehreli wrote:
 On 4/21/21 8:37 AM, realhet wrote:
 On Wednesday, 21 April 2021 at 10:47:08 UTC, Mike Parker wrote:
 On Wednesday, 21 April 2021 at 10:00:51 UTC, realhet wrote:

 It has access to the context of its enclosing scope (via an 
 added hidden field).
Thanks! So it is unsafe to return a non-static nested struct from a function. But it is useful to pass it forward into other functions.
Not at all. (D is good at preventing such bugs anyway.) The local context that the nested struct object uses becomes the context of that object.
Wow, this information is really out of the box for me. I have one misconception less now. (I never used a language with GC before and this thing requires a GC for sure.) /------------------------------------------------------- auto uiDeclare(void delegate() fun){ struct UiObject{ //void delegate() fun; <- not needed, it captures fun in the params void render(){ fun(); } } return UiObject(); } long rec(long a, long c){ return a<c ? rec(a+1, c) : a; } void main() { int a = 5; auto b = [ uiDeclare({ writeln("boop", a); }), uiDeclare({ writeln("boop", a+1); })]; rec(0, 123456); // destroy the stack to make sure b.each!"a.render"; } Indeed it's not using the stack. And it also works when a delegates captures its scope. In my immediate GUI interface I'm using delegates all the time with the my misconception of I only allowed to call them from inside the function I passed them into. For example: Row({ Text(clBlue, "Hello"); Img(`pictures\pic1.jpg`); }); will call the delegate from inside, not save it for later use. And if I save the delegate inside the Row() function (I mark UI generating functions with a capital letter), it is protected from the GC and can be used later in rendering time... Too bad, the data it uses at that later moment is possibly changed already. Anyways, I've learned a lot now. Thank you!
Apr 22 2021