(DMD) problem with closures/delegate literals and structs?

H. S. Teoh hsteoh at quickfur.ath.cx
Sat Dec 7 21:50:34 PST 2013


On Sun, Dec 08, 2013 at 12:17:02AM +0000, Iain Buclaw wrote:
> On 7 December 2013 20:30, H. S. Teoh <hsteoh at quickfur.ath.cx> wrote:
> > On Sat, Dec 07, 2013 at 07:32:46PM +0100, Johannes Pfau wrote:
[...]
> >> What I meant is this: In the first example I posted,
> >> http://dpaste.dzfl.pl/433c0a3d
> >> the delegate does not access _function variables_. It only accesses
> >> the this pointer. So there's no need for it to be a real closure
> >> and allocate memory, it could instead be a normal delegate with the
> >> context pointer simply set to the this pointer at the moment the
> >> delegate is created.
> >
> > The problem is that when `this` is closed over, it's one thing, but
> > when the delegate is invoked later, `this` may no longer be valid.
> > For example:
> >
> >         struct S {
> >                 int x = 123; // canary
> >                 void delegate() getDelegate() {
> >                         // Closes over `this`
> >                         return () => x;
> >                 }
> >         }
> >
> >         void delegate() dg;
> >
> >         S makeStruct() {
> >                 S s;
> >                 dg = s.getDelegate();
> >                 return s;
> >         }
> >
> >         void main() {
> >                 auto s = makeStruct();
> >                 dg(); // <-- NG
> >         }
> >
> 
> I feel inclined to make that always make that sort of usage an error.
> :)

I agree. But the problem is that currently the compiler will happily
accept this and emit code for it, which will screw up at runtime. So the
compiler should be fixed to either reject this outright, or somehow
generate code that does the Right Thing.


T

-- 
First Rule of History: History doesn't repeat itself -- historians merely repeat each other.


More information about the D.gnu mailing list