Don wrote:
bearophile wrote:
I have also tested the semantics of nested function purity:

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

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

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

Compiled without inlining:
-O -release

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

double_sqr:
L0:     push    EAX
        push    EAX
        xor EAX,EAX
        call    near ptr double_sqr.sqr
        push    EAX
        sub ESP,4
        xor EAX,EAX
        push    dword ptr 8[ESP]
        call    near ptr double_sqr.sqr
        add ESP,4
        mov ECX,EAX
        pop EAX
        add EAX,ECX
        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 to!(int)()
        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

There's one call to double_sqr but unfortunately two to double_sqr.sqr.

Bye,
bearophile

Yes. Actually, marking a nested function as pure doesn't make much sense.
It's entirely equivalent to moving it outside the function; a nested pure function shouldn't be able to access any members of the enclosing function, otherwise it's not pure. But DMD doesn't enforce that, and so it creates inefficient and possibly buggy code.

The bug is bugzilla 2807.

I'm not sure that nested pure member functions should be legal.

And it turns out that sqr() isn't actually pure, in the same way that it wasn't nothrow in your first example. The 'pure' marker is silently being ignored. If you put the 'pure' at the end, you get bug 2807.

--

Reply via email to