www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - tail recursive delegates

reply kzed port70.net writes:
Hello,
 so I wanted to test whether tail recursion optimization worked with
delegates... And apparently I'm doing something wrong :) (Simple tail
recursion with functions worked, as in gcc.)
 I'm using the GNU compiler; -O2 turns on tail recursion opt as with
gcc.
 Can someone help?

I'll paste my test procedure.

Thanks,
 Mate

test.d:
----
int delegate(int, int) counter(int by)
{
    int cntr(int i, int acc) {
        printf("cntr i=%d acc=%d by=%d\n", i, acc, by);
        if(i < 1) return acc;
        return cntr(i - 1, acc += by);
    }

    return &cntr;
}

int main()
{
    int delegate(int, int) count = counter(3);
    printf("%d", count(10, 0));
    return 0;
}
---
eris ~% gdc -o test test.d
eris ~% ./test
cntr i=10 acc=0 by=3
cntr i=9 acc=3 by=3
cntr i=8 acc=6 by=3
cntr i=7 acc=9 by=3
cntr i=6 acc=12 by=3
cntr i=5 acc=15 by=3
cntr i=4 acc=18 by=3
cntr i=3 acc=21 by=3
cntr i=2 acc=24 by=3
cntr i=1 acc=27 by=3
cntr i=0 acc=30 by=3
30

eris ~% gdc -o test test.d  -O2
eris ~% ./test
cntr i=10 acc=0 by=6530176
cntr i=9 acc=6530176 by=6530176
cntr i=8 acc=13060352 by=6530176
cntr i=7 acc=19590528 by=6530176
cntr i=6 acc=26120704 by=6530176
cntr i=5 acc=32650880 by=6530176
cntr i=4 acc=39181056 by=6530176
cntr i=3 acc=45711232 by=6530176
cntr i=2 acc=52241408 by=6530176
cntr i=1 acc=58771584 by=6530176
cntr i=0 acc=65301760 by=6530176
65301760
Jul 15 2008
parent BCS <ao pathlink.com> writes:
Reply to kzed port70.net,

 Hello,
 so I wanted to test whether tail recursion optimization worked with
 delegates... And apparently I'm doing something wrong :) (Simple tail
 recursion with functions worked, as in gcc.)
 I'm using the GNU compiler; -O2 turns on tail recursion opt as with
 gcc.
 Can someone help?
 I'll paste my test procedure.
 
 Thanks,
 Mate
 test.d:
 ----
 int delegate(int, int) counter(int by)
 {
 int cntr(int i, int acc) {
 printf("cntr i=%d acc=%d by=%d\n", i, acc, by);
 if(i < 1) return acc;
 return cntr(i - 1, acc += by);
 }
 return &cntr;
 }
 int main()
 {
 int delegate(int, int) count = counter(3);
 printf("%d", count(10, 0));
 return 0;
 }

'by' is a stack frame variable of counter and is invalid after counter returns. D 1.0 doesn't have full closures. The first case just happens to work because is some how doesn't stomp on the old stack frame. The second case changes something and then does stomp on stuff. int delegate(int, int) counter(int by) { struct Ret { int by; int cntr(int i, int acc) { printf("cntr i=%d acc=%d by=%d\n", i, acc, by); if(i < 1) return acc; return cntr(i - 1, acc += by); } auto ret = new Ret; ret.by=by; return &ret.cntr; } that should work.
 ---
 eris ~% gdc -o test test.d
 eris ~% ./test
 cntr i=10 acc=0 by=3
 cntr i=9 acc=3 by=3
 cntr i=8 acc=6 by=3
 cntr i=7 acc=9 by=3
 cntr i=6 acc=12 by=3
 cntr i=5 acc=15 by=3
 cntr i=4 acc=18 by=3
 cntr i=3 acc=21 by=3
 cntr i=2 acc=24 by=3
 cntr i=1 acc=27 by=3
 cntr i=0 acc=30 by=3
 30
 eris ~% gdc -o test test.d  -O2
 eris ~% ./test
 cntr i=10 acc=0 by=6530176
 cntr i=9 acc=6530176 by=6530176
 cntr i=8 acc=13060352 by=6530176
 cntr i=7 acc=19590528 by=6530176
 cntr i=6 acc=26120704 by=6530176
 cntr i=5 acc=32650880 by=6530176
 cntr i=4 acc=39181056 by=6530176
 cntr i=3 acc=45711232 by=6530176
 cntr i=2 acc=52241408 by=6530176
 cntr i=1 acc=58771584 by=6530176
 cntr i=0 acc=65301760 by=6530176
 65301760

Jul 15 2008