nested functions and closures

Steven Schveighoffer schveiguy at yahoo.com
Mon Feb 11 14:03:22 PST 2013


On Mon, 11 Feb 2013 13:59:36 -0500, Johannes Pfau <nospam at example.com>  
wrote:

> When debugging gdc I've found some at least for me interesting
> behavior which I'm trying to understand now:
>
> ----
> auto testFunction() {
>     int a = 41;
>     int nestedFunc() { return ++a; }
>
>     struct NestedStruct {
>         int answer() { return nestedFunc(); }
>     }
>
>     return NestedStruct();
> }
>
> writeln(testFunction().answer());
> ----
>
> This is valid D code, creates a closure.
>
> ----
> class testClass
> {
>     int a = 41;
>     int nestedFunc() { return ++a; }
>
>     struct NestedStruct {
>         int answer() { return nestedFunc(); }
>     }
>    auto getStruct() { return NestedStruct(); }
> }
>
> writeln((new TestClass()).getStruct().answer);
> ----
>
> This does not compile:
> test.d(33): Error: this for nestedFunc needs to be type testClass not
> type NestedStruct
>
> Is this intended? It seems to be very similar to the function closure
> code. Couldn't NestedStruct just get a pointer to the testClass to
> access its variables? Or am I missing something?
>
> Everything works fine if NestedStruct is a class and not a struct so I
> guess this functionality was disabled deliberately. But why? And why
> wasn't using a nested struct in functions in a similar way disallowed as
> well?

A nested class has an outer pointer to it's owner class.  You cannot  
instantiate a nested class without it's owner class.

A nested struct does NOT have a pointer to it's owner class.  It's simply  
typed inside the class' namespace.

FYI, nested classes were enshrined with a pointer to an outer instance for  
two reasons:

1. Their footprint is larger, not as big a hit to add another pointer.
2. To allow porting of Java code.

Structs are POD for the most part, and are much more "bare metal" than  
classes.

Nested structs could be given an instance pointer to the owner, but I  
think we would need a new construct for that.

For your problem at hand, you may want to consider using interfaces  
instead.  Or you can possibly embed the owner pointer manually.

-Steve


More information about the Digitalmars-d mailing list