www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Extending the lifetime of scope objects

reply =?UTF-8?B?QWxpIMOHZWhyZWxp?= <acehreli yahoo.com> writes:
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? :)

Thank you,
Ali
Jul 20 2010
parent torhu <no spam.invalid> writes:
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.
Jul 20 2010