Forcing compile time evaluation of pure functions

bearophile bearophileHUGS at lycos.com
Thu Jun 30 01:43:05 PDT 2011


scarrow:

> Annoyingly, however, I can't do the following at compile time:
> 
>     f(Hash("foo"));
> 
> I'm not sure what the point is in distinguishing between these two cases.

Walter has decided that he doesn't like the D compiler to arbitrary run at compile time arbitrary long to run code. This is named partial compilation and it has some traps. In theory I agree with you that I'd like the compiler to be smarter, but in practice Walter prefers control here, so DMD runs compile-time functions only if you explicitly ask their result to be known at compile-time.

Note that in D you are able to run at compile time functions that are pure just in the execution path that's used at compile-time, even if on the whole they are not pure. This works:

int x;
int foo(bool b, int y) { if (b) return x; else return y; }
enum result = foo(false, 10);


> I want to be able to write:
> 
>     string s = "bar";
>     f(Hash("foo"));    // invoke the compile time version and pass a constant to f
>     f(Hash(s));    // invoke the runtime version and pass the result to f

Is this good enough?

/**
To execute a function at compile time.
*/
template StaticEval(A...) {
   enum typeof(A[0]) StaticEval = A[0];
}

void f(size_t) {}
size_t Hash(string s) { return 0U; }

void main() {
    f(Hash("foo"));
    f(StaticEval!(Hash("foo")));
}


The second Hash runs at compile-time, there is only one call to _D4test4HashFAyaZk (compiled with -O -release, without -inline):

__Dmain comdat
L0:     push    EAX
        push    dword ptr FLAT:_DATA[0Ch]
        push    dword ptr FLAT:_DATA[08h]
        call    near ptr _D4test4HashFAyaZk
        call    near ptr _D4test1fFkZv
        xor EAX,EAX
        call    near ptr _D4test1fFkZv
        xor EAX,EAX
        pop ECX
        ret

Bye,
bearophile


More information about the Digitalmars-d-learn mailing list