www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Nested function bug?

reply Ed McCardell <edmccard hotmail.com> writes:
I ran into a strange and hard-to-describe problem with nested functions 
closing over the argument to their enclosing function.

When a nested function (A) returns the value of another nested function 
(B) that returns a parameter of the enclosing function (C), and when (A) 
is returned from (C), then calling (A) returns an incorrect value if (A) 
has a parameter of class type (it works when (A) has no class parameters).

The code below demonstrates this (using DMD 2.058, no optimizations). Is 
this a bug?


auto foo(T)(int val)
{
     int nested()
     {
         return val;
     }

     int escaping(T ignored)
     {
         return nested();
     }

     return &escaping;

//    return &nested; // this works
}

struct Bar {}

class Baz {}

void main()
{
     auto func1 = foo!int(55);
     auto val1 = func1(12);
     assert(val1 == 55); // works fine with integral type

     auto func2 = foo!Bar(55);
     Bar bar;
     auto val2 = func2(bar);
     assert(val2 == 55); // works fine with struct

     auto func3 = foo!Baz(55);
     auto baz = new Baz();
     auto val3 = func3(baz);
     assert(val3 == 55); // fails; val3 is different value on each run
}
Mar 30 2012
next sibling parent reply Walter Bright <newshound2 digitalmars.com> writes:
On 3/30/2012 1:13 PM, Ed McCardell wrote:
 I ran into a strange and hard-to-describe problem with nested functions closing
 over the argument to their enclosing function.

 When a nested function (A) returns the value of another nested function (B)
that
 returns a parameter of the enclosing function (C), and when (A) is returned
from
 (C), then calling (A) returns an incorrect value if (A) has a parameter of
class
 type (it works when (A) has no class parameters).

 The code below demonstrates this (using DMD 2.058, no optimizations). Is this a
 bug?

Looks like one. Please report this to http://d.puremagic.com/issues/enter_bug.cgi?product=D
Mar 30 2012
parent Ed McCardell <edmccard hotmail.com> writes:
On 03/30/2012 04:45 PM, Walter Bright wrote:
 On 3/30/2012 1:13 PM, Ed McCardell wrote:
 The code below demonstrates this (using DMD 2.058, no optimizations).
 Is this a
 bug?

Looks like one. Please report this to http://d.puremagic.com/issues/enter_bug.cgi?product=D

Done: http://d.puremagic.com/issues/show_bug.cgi?id=7801
Mar 30 2012
prev sibling parent reply Andrej Mitrovic <andrej.mitrovich gmail.com> writes:
On 3/30/12, Ed McCardell <edmccard hotmail.com> wrote:
 The code below demonstrates this (using DMD 2.058, no optimizations). Is
 this a bug?

You mean the result is 55 when you uncomment "return &nested;"? All asserts pass for me when I use that return. Otherwise when using "return &escaping;" I get: 1244764 1244764 4202631 2.058 win32.
Mar 30 2012
parent Ed McCardell <edmccard hotmail.com> writes:
On 03/30/2012 04:51 PM, Andrej Mitrovic wrote:
 You mean the result is 55 when you uncomment "return&nested;"? All
 asserts pass for me when I use that return. Otherwise when using
 "return&escaping;" I get:

 1244764
 1244764
 4202631

 2.058 win32.

On 64-bit linux, the first two asserts always pass using either "return &nested" or "return &escaping". Just checked on 32-bit linux and I see the same behavior you are, with all three asserts failing using "return &escaping". --Ed
Mar 30 2012