www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Voldemort type: getPoint()

reply Salih Dincer <salihdb hotmail.com> writes:
As long as the Voldemort type lives on, does int x, y legally 
live on?

```d
auto getPoint()
{
   int x, y; // major issue

   enum type = "2D";
   struct Point(string Id)
   {
     static int _x = 1024;
     static int _y = 768;
     string toString() {
       import std.format;
       return format("Limit: %dx%d px.",
                                _x, _y);
     }
     void set(int a, int b) { x = a; y = b; }
     uint area() { return x * y; }
     auto get() { return this; }
   }
   auto px = Point!type();
   return px.get;
}
```

For test:

```d
   auto p1 = getPoint();
   p1.set(2, 21);
   p1.area.writeln(" MP, ", p1);
   typeof(p1).stringof
   .writefln!"%s  %s"(&p1);

   p1.set(10, 100);
   p1.area.writeln(" MP, ", p1);


   auto p2 = getPoint();
   p2.area.writeln(" MP, ", p2);
   p2.set(3, 21);
   typeof(p2).stringof
   .writefln!"%s  %s"(&p2);

   p1.area.writeln(" MP, ", p1);
   p2.area.writeln(" MP, ", p2);
```

Outputs:

42 MP, Limit: 1024x768 px.
Point!"2D" 7FFD328DB770 1000 MP, Limit: 1024x768 px. 0 MP, Limit: 1024x768 px. Point!"2D" 7FFD328DB788 1000 MP, Limit: 1024x768 px. 63 MP, Limit: 1024x768 px. SDB 79
Apr 26 2022
parent "H. S. Teoh" <hsteoh quickfur.ath.cx> writes:
On Tue, Apr 26, 2022 at 06:20:50PM +0000, Salih Dincer via Digitalmars-d wrote:
 As long as the Voldemort type lives on, does int x, y legally live on?
 
 ```d
 auto getPoint()
 {
   int x, y; // major issue
 
   enum type = "2D";
   struct Point(string Id)
   {
     static int _x = 1024;
     static int _y = 768;
     string toString() {
       import std.format;
       return format("Limit: %dx%d px.",
                                _x, _y);
     }
     void set(int a, int b) { x = a; y = b; }
     uint area() { return x * y; }
     auto get() { return this; }
   }
   auto px = Point!type();
   return px.get;
 }
 ```
That's a closure over x and y, so yes, they will live on. The compiler will detect that a closure is required, so it will allocate them on the heap instead of the stack, and the struct Point will have a hidden context pointer that points to the heap allocation that contains the values of x and y. As long as a Point instance still exists that points to the allocated block, the GC will not collect it. In general, though, I don't recommend closing over local variables in a struct, unless you mean to share those variables across copies of the struct. In the above example, if you call getPoint twice, you will get two Point structs pointing to different copies of x and y. But if you make a copy of either struct, you will end up with two structs that share the *same* set of x and y values (so changes to one will be seen by the other), which may or may not be what you want. This can make for rather confusing behaviour if these structs get passed around to other code. My usual practice is to avoid such struct closures, and to store independent copies of x and y inside the struct itself instead (just make them private and move it into a separate module if you're paranoid). T -- "A one-question geek test. If you get the joke, you're a geek: Seen on a California license plate on a VW Beetle: 'FEATURE'..." -- Joshua D. Wachs - Natural Intelligence, Inc.
Apr 26 2022