www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - delegates and temporary struct

reply "Jack Applegame" <japplegame gmail.com> writes:
Look at this code:
import std.stdio;

class Foo {
  int value = 123456;
}

struct Bar {
  this(Foo f) { foo = f; }
   property auto lambda() {
    return (){ writefln("value = %s", foo.value); };
  }
  Foo foo;
}
auto getLambda(Foo f) {
  return Bar(f).lambda; // lambda closure points to temporary 
 Bar on the stack
}
void main() {
  Foo foo = new Foo;
  auto lambda = getLambda(foo);
  lambda(); // undefined behaviour? prints some number, but not 
 123456
}
It compiles, but result is unpredictable. Platform: Windows 7, dmd 2.062 For reproducing this behaviour it's necessary to omit -inline and -O flags, try simple "rdmd test.d"
May 16 2013
next sibling parent reply "Maxim Fomin" <maxim maxim-fomin.ru> writes:
On Thursday, 16 May 2013 at 22:53:56 UTC, Jack Applegame wrote:
 Look at this code:
import std.stdio;

class Foo {
 int value = 123456;
}

struct Bar {
 this(Foo f) { foo = f; }
  property auto lambda() {
   return (){ writefln("value = %s", foo.value); };
 }
 Foo foo;
}
auto getLambda(Foo f) {
 return Bar(f).lambda; // lambda closure points to temporary 
 Bar on the stack
}
void main() {
 Foo foo = new Foo;
 auto lambda = getLambda(foo);
 lambda(); // undefined behaviour? prints some number, but not 
 123456
}
It compiles, but result is unpredictable. Platform: Windows 7, dmd 2.062 For reproducing this behaviour it's necessary to omit -inline and -O flags, try simple "rdmd test.d"
http://d.puremagic.com/issues/show_bug.cgi?id=9352
May 16 2013
parent 1100110 <0b1100110 gmail.com> writes:
On 05/16/2013 09:21 PM, Maxim Fomin wrote:
 On Thursday, 16 May 2013 at 22:53:56 UTC, Jack Applegame wrote:
 Look at this code:
 import std.stdio;

 class Foo {
 int value =3D 123456;
 }

 struct Bar {
 this(Foo f) { foo =3D f; }
  property auto lambda() {
   return (){ writefln("value =3D %s", foo.value); };
 }
 Foo foo;
 }
 auto getLambda(Foo f) {
 return Bar(f).lambda; // lambda closure points to temporary Bar on
 the stack
 }
 void main() {
 Foo foo =3D new Foo;
 auto lambda =3D getLambda(foo);
 lambda(); // undefined behaviour? prints some number, but not 123456
 }
It compiles, but result is unpredictable. Platform: Windows 7, dmd 2.062 For reproducing this behaviour it's necessary to omit -inline and -O flags, try simple "rdmd test.d"
=20 http://d.puremagic.com/issues/show_bug.cgi?id=3D9352
I get an incorrect but consistent number using dmd -m32 test.d and the correct number using dmd -m64 test.d on Linux.
May 16 2013
prev sibling parent "Steven Schveighoffer" <schveiguy yahoo.com> writes:
On Thu, 16 May 2013 18:53:55 -0400, Jack Applegame <japplegame gmail.com>  
wrote:

 Look at this code:
 import std.stdio;

 class Foo {
  int value = 123456;
 }

 struct Bar {
  this(Foo f) { foo = f; }
   property auto lambda() {
    return (){ writefln("value = %s", foo.value); };
  }
  Foo foo;
 }
 auto getLambda(Foo f) {
  return Bar(f).lambda; // lambda closure points to temporary Bar on the  
 stack
 }
 void main() {
  Foo foo = new Foo;
  auto lambda = getLambda(foo);
  lambda(); // undefined behaviour? prints some number, but not 123456
 }
It compiles, but result is unpredictable. Platform: Windows 7, dmd 2.062 For reproducing this behaviour it's necessary to omit -inline and -O flags, try simple "rdmd test.d"
Using struct delegates is VERY frought with danger. You must ensure the struct is alive when the delegate is called. I don't think the compiler can detect the cases where it's not and allocate a closure. I also have found this out the hard way... Only recourse is to ensure the struct is on the heap. -Steve
May 17 2013