Question of delegate literals and return from function(GDC, DMD, LDC)

Steven Schveighoffer schveiguy at yahoo.com
Mon Feb 2 09:05:52 PST 2009


"amaury pouly" wrote
> Hello,
> I have a little question about D: I want to have a function returning a 
> delegate and more precisely a delegate literal that uses one of the 
> arguments of the function. Here is an example:
>
> int delegate(int) test(int[] tab)
> {
>    return (int d)
>    {
>        int sum;
>        foreach(i;tab)
>            sum+=i*d;// stupid computation
>        return sum;
>    };
> }
>
> int main()
> {
>    auto res=test([1,2,3,4,5,6])(4);
>    return res;
> }
> Of course this example is stupid but the idea is here. The point is that 
> if I compile and run this code with DMD it works fine whereas it segfaults 
> with GDC and LDC(LLVM D). I also know a fix for the segfault with both GDC 
> and LDC:
>
> int delegate(int) test(int[] tab)
> {
>    struct Foo
>    {
>        int[] tab;
>
>        int fn(int d)
>        {
>            int sum;
>            foreach(i;tab)
>                sum+=i*d;// stupid computation
>            return sum;
>        }
>    }
>
>    Foo *f=new Foo;
>    f.tab=tab;
>    return &f.fn;
> }
>
> int main()
> {
>    auto res=test([1,2,3,4,5,6])(4);
>    return res;
> }
>
> My question is the following: is this a bug of GDC/LDC or is this the 
> expected behaviour ? The second solution must always work but I'm unsure 
> about the first one. Indeed, the specification says that a delegate shall 
> not reference a stack parameter which is logical but it says nothing about 
> function arguments.

Expected behavior.  Function arguments *are* stack parameters.  Even though 
you are passing a parameter whose storage is defined in the main function 
(and technically, is allocated on the heap), the 'tab' parameter to test is 
a stack-based struct which contains the pointer to the array.  When main 
calls the delegate, it overwrites that struct with new data, because the 
stack frame is reused, and therefore, it's anyones guess why it works on 
dmd.

-Steve 





More information about the Digitalmars-d mailing list