digitalmars.D.learn - Extending the lifetime of scope objects
- =?UTF-8?B?QWxpIMOHZWhyZWxp?= (41/41) Jul 20 2010 What are all the cases that extend the lifetime of scoped objects?
- torhu (11/50) Jul 20 2010 When a local variable in a function (or delegate) is part of a nested
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
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








 
  
  
  torhu <no spam.invalid>
 torhu <no spam.invalid>