Three subtle cases of tail recursion (Re: DMD 1.001 release)

Kazuhiro Inaba kiki at kmonos.net
Wed Jan 24 05:55:20 PST 2007


> http://www.digitalmars.com/d/changelog.html
> tail recursion works again 

Fine!! But it seems buggy in some corner cases.

1. Nested function

    // quirky way to call dg() n times
    void repeat( int n, void delegate() dg ) {
      if( n&1 ) dg();
      if( n/2 ) repeat( n/2, {dg();dg();} );
    }
    void main() {
      repeat( 10, {printf("Hello\n");} );
    }

  If compiled with -O flag, this program goes into an infinite loop.
  Tail recursive call of repeat function reuses the stack frame, which is
  still referenced by the anonymous delegate, too early.

2. Scope statemenmt

    int scp( int n ){
      if( n==0 ) return 0;
      scope(exit) printf("%d",n);
      return scp(n-1);
    }
    void main() {
      scp(5);
    }

  Without -O flag, it emits 12345 (correct).
  With -O flag enabled, it emits 43210 (at least in my environment.)

3. Conditional expression

    // return in an if statement is optimized as a tail recursion
    long f_if( long n, long acc=0 ) {
      if(n) return f_if( n-1, n+acc ); else return acc;
    }
    // same function written with a conditional statement is not
    long f_cd( long n, long acc=0 ) {
      return n ? f_cd( n-1, n+acc ) : acc;
    }
    void main() {
      printf("%lld\n", f_if(1000000)); // 500000500000
      printf("%lld\n", f_cd(1000000)); // Error: Stack Overflow
    }

  This is not a bug, but it would be preferable if dmd detects and
  optimizes the "return cond ? recursive_call : ..." form.


-- 
Kazuhiro Inaba




More information about the Digitalmars-d-announce mailing list