spir:

> It seems to be the kind of stupid issue that will make you laugh about me. 
> But 
> I cannot grasp and want to move forward anyway; so, let us be bold and take 
> the 
> risk ;-)

Be bold. Understanding things is much more important. I've being wrong hundreds 
of times on D newsgroups, but I'm getting better.

> This fails! It even fails "doubly"...

Reduced program (and Walter thinks that avoiding printf-related bugs is not 
important. He's wrong. I use printf often enough in D):


import core.stdc.stdio: printf;
struct Foo {
    bool b;
    this(bool b_) { this.b = b_; }
}
enum Foo* TRUE = new Foo(true);
enum Foo* FALSE = new Foo(false);
Foo* not(Foo* op) {
    return (op == TRUE) ? FALSE : TRUE;
}
void main() {
    //assert(not(TRUE) == FALSE);
    printf("%x\n", TRUE);
    printf("%x\n", FALSE);
    printf("%x\n", not(TRUE));
    printf("%x\n", not(not(TRUE)));
}


> Here, I operate on the structs instead of on the pointers, both to perform 
> the 
> operation and in the assert. What I understand is: all happens like if D 
> would 
> copy the pointed structs on parameter passing and on return. I thought D 
> would 
> only copy the pointers (in both directions), which would let me compare said 
> pointers directly.
> What do I miss?

DMD is not copying the structs, just pointers.

I think it's happening something like with enum associative arrays. Pointers 
are run-time things. You are asking for a new at compile-time. This is the asm 
produced by that program (-O -release):


_D4test3Foo6__ctorMFNcbZS4test3Foo      comdat
                push    EAX
                mov     CL,8[ESP]
                mov     [EAX],CL
                pop     ECX
                ret     4

_D4test3notFPS4test3FooZPS4test3Foo     comdat
L0:             push    EAX
                mov     ECX,offset FLAT:_D20TypeInfo_PS4test3Foo6__initZ
                push    EAX
                push    EBX
                push    1
                push    ECX
                call    near ptr __d_newarrayT
                add     ESP,8
                mov     EAX,EDX
                push    1
                call    near ptr _D4test3Foo6__ctorMFNcbZS4test3Foo
                cmp     EAX,8[ESP]
                jne     L3D
                mov     EDX,offset FLAT:_D20TypeInfo_PS4test3Foo6__initZ
                push    1
                push    EDX
                call    near ptr __d_newarrayT
                add     ESP,8
                mov     EAX,EDX
                push    0
                call    near ptr _D4test3Foo6__ctorMFNcbZS4test3Foo
                jmp short       L56
L3D:            mov     EBX,offset FLAT:_D20TypeInfo_PS4test3Foo6__initZ
                push    1
                push    EBX
                call    near ptr __d_newarrayT
                add     ESP,8
                mov     EAX,EDX
                push    1
                call    near ptr _D4test3Foo6__ctorMFNcbZS4test3Foo
L56:            pop     EBX
                add     ESP,8
                ret

__Dmain comdat
L0:             push    EAX
                mov     EAX,offset FLAT:_D20TypeInfo_PS4test3Foo6__initZ
                push    EBX
                push    ESI
                push    1
                push    1
                push    EAX
                call    near ptr __d_newarrayT
                add     ESP,8
                mov     EAX,EDX
                call    near ptr _D4test3Foo6__ctorMFNcbZS4test3Foo
                mov     ECX,offset FLAT:_DATA
                push    EAX
                push    ECX
                call    near ptr _printf
                mov     EDX,offset FLAT:_D20TypeInfo_PS4test3Foo6__initZ
                push    0
                push    1
                push    EDX
                call    near ptr __d_newarrayT
                add     ESP,8
                mov     EAX,EDX
                call    near ptr _D4test3Foo6__ctorMFNcbZS4test3Foo
                mov     EBX,offset FLAT:_DATA
                push    EAX
                push    EBX
                call    near ptr _printf
                mov     ESI,offset FLAT:_D20TypeInfo_PS4test3Foo6__initZ
                push    1
                push    1
                push    ESI
                call    near ptr __d_newarrayT
                add     ESP,8
                mov     EAX,EDX
                call    near ptr _D4test3Foo6__ctorMFNcbZS4test3Foo
                call    near ptr _D4test3notFPS4test3FooZPS4test3Foo
                push    EAX
                push    EBX
                call    near ptr _printf
                push    1
                push    1
                push    ESI
                call    near ptr __d_newarrayT
                add     ESP,8
                mov     EAX,EDX
                call    near ptr _D4test3Foo6__ctorMFNcbZS4test3Foo
                call    near ptr _D4test3notFPS4test3FooZPS4test3Foo
                call    near ptr _D4test3notFPS4test3FooZPS4test3Foo
                push    EAX
                push    EBX
                call    near ptr _printf
                add     ESP,020h
                xor     EAX,EAX
                pop     ESI
                pop     EBX
                pop     ECX
                ret


My suspect is confirmed, DMD is acting as with enum associative arrays. This is 
a compiler bug. DMD has to act correctly and not create a struct every time, or 
it has to give a compile-time error. Not this mess.

Bye,
bearophile

Reply via email to