Nesting in pure functions

bearophile bearophileHUGS at lycos.com
Mon Apr 6 02:36:16 PDT 2009


Don:
> But this one works:
> 
> pure int double_sqr(int x) {
>      int z;
>      int do_sqr(int y) pure { return y*y; }
>      z = do_sqr(x);
>      z += do_sqr(x);
>      return z;
> }

Right, thank you.
But why the pure is after the argument list? I didn't even know that syntax is allowed.


I have then compiled:

import std.c.stdio: printf;
import std.conv: toInt;

pure int double_sqr(int x) {
     int sqr(int y) pure { return y * y; }
     return sqr(x) + sqr(x);
}

void main(string[] args) {
    int x = args.length == 2 ? toInt(args[1]) : 10;
    int y = double_sqr(x) + double_sqr(x);
    printf("4 * x * x = %d\n", y);
}


The asm generated by D2 with no inlining:

sqr:
        mov EAX,4[ESP]
        imul    EAX,EAX
        ret 4

double_sqr:
L0:     push    EAX
        push    EAX
        xor EAX,EAX
        call    near ptr sqr
        add EAX,EAX
        pop ECX
        ret

main:
L0:     push    EAX
        cmp dword ptr 8[ESP],2
        jne L1D
        mov EDX,0Ch[ESP]
        mov EAX,8[ESP]
        push    dword ptr 0Ch[EDX]
        push    dword ptr 8[EDX]
        call    near ptr toInt
        jmp short   L22
L1D:    mov EAX,0Ah
L22:    call    near ptr double_sqr
        add EAX,EAX
        mov ECX,offset FLAT:_DATA
        push    EAX
        push    ECX
        call    near ptr printf

So pure is correctly optimized in both places.

I don't know why sqr is written like this:

sqr:
        imul    EAX,EAX
        ret

Bye,
bearophile



More information about the Digitalmars-d mailing list