Extending the lifetime of scope objects

torhu no at spam.invalid
Tue Jul 20 14:32:30 PDT 2010


On 20.07.2010 21:54, Ali Çehreli wrote:
> What are all the cases that extend the lifetime of scoped objects?
>
> Binding a delegate to a scope object extends the lifetime of that
> object, which would normally end upon exiting that scope. The lifetime
> of i is extended here:
>
> int delegate(int) make_delegate()
> {
>       int i;    // lives as long as the returned delegate lives
>
>       return (int param) {
>           return i + param;         // uses i
>       };
> }
>
> void main()
> {
>       auto del = make_delegate();
>       del(42);                      // uses i
> }
>
> I was surprised to discover that, the same does not apply to struct
> objects, *if* the struct has a destructor:
>
> struct S
> {
>       int i;
>
>       ~this()  // prevents life extension
>       {}
> }
>
> int delegate(int) make_delegate()
> {
>       auto s = S();
>
>       return (int param) {
>           return s.i + param;
>       };
> }
>
> void main()
> {
>       auto del = make_delegate();
>       del(42);
> }
>
> Error: variable deneme.make_delegate.s has scoped destruction, cannot
> build closure
>
> Are the "life extending" cases short and simple? What are they? :)

When a local variable in a function (or delegate) is part of a nested 
delegate's context, that variable is heap allocated.  Which just means 
the GC will collect it sometime after the last reference is gone.  In 
your first example, it's like you did int* i = new int;

What is supposed to happen with your struct example doesn't seem to be 
documented, neither in the docs or TDPL.  Could be just an accident that 
it doesn't work.  Or it could be on purpose, but there's no way of 
knowing without asking Walter or Andrei.  There's a slight chance taking 
a reference to the struct itself instead of just a member will work.  I 
guess you just hit a marginal case here.


More information about the Digitalmars-d-learn mailing list