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