comparing pointers passed to and returned from funcs
bearophile
bearophileHUGS at lycos.com
Tue Mar 1 14:53:41 PST 2011
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
More information about the Digitalmars-d-learn
mailing list