various questions

bearophile bearophileHUGS at lycos.com
Fri Jul 30 04:03:11 PDT 2010


Jason Spencer:
> I nievely went and replaced "foreach (t; Iota!(str_types.length))"
> with "foreach (t; str_types.length)", since the length of that array
> is known at compile-time.  That of course bombed, but I don't quite
> get why.  Is the compiler actually evaluating the foreach loop at
> compile time?  How could it, when the body makes run-time checks?  If
> it's not, why doesn't my change work?

foreach (t; str_types.length) doesn't work because integral values are not iterable. You need a range, collection or tuple.

foreach (t; 0 .. str_types.length) doesn't work in that code because it's a run-time foreach.

The  Iota!(n) creates a tuple of the values 0, 1, 2 ... n-1.

The foreach done on a tuple is a static foreach, it's done at compile-time, so my code is a way to perform a compile-time unrolling of the if-goto body. You can see it with this example (normally DMD is not able to perform loop unrolling):


import std.typetuple: TypeTuple;
import std.c.stdio: printf;

template Iota(int stop) {
    static if (stop <= 0)
        alias TypeTuple!() Iota;
    else
        alias TypeTuple!(Iota!(stop-1), stop-1) Iota;
}
void main() {
    foreach (i; Iota!(5)) {
        enum int n = i;
        printf("%d\n", n);
    }
}


The resulting asm:

__Dmain comdat
        push    EBX
        push    0
        mov EAX,offset FLAT:_DATA
        push    EAX
        call    near ptr _printf
        add ESP,8
        push    1
        mov ECX,offset FLAT:_DATA
        push    ECX
        call    near ptr _printf
        add ESP,8
        push    2
        mov EDX,offset FLAT:_DATA
        push    EDX
        call    near ptr _printf
        add ESP,8
        push    3
        mov EBX,offset FLAT:_DATA
        push    EBX
        call    near ptr _printf
        add ESP,8
        push    4
        push    EBX
        call    near ptr _printf
        add ESP,8
        xor EAX,EAX
        pop EBX
        ret


I suggest you to use a variant of my last version of the code because it contains some asserts and static asserts that improve code safety a bit.

See also this enhancement request of mine:
http://d.puremagic.com/issues/show_bug.cgi?id=4085

Bye,
bearophile


More information about the Digitalmars-d-learn mailing list