Thread overview | ||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
March 01, 2011 comparing pointers passed to and returned from funcs | ||||
---|---|---|---|---|
| ||||
Hello,
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 ;-)
I'm modeling a little dynamic language. Elements (values, objects) are pointers to structs (actually tagged unions) allocated on the heap. I have a problem in passing and returning those pointers to and from primitive procedures.
Precisely, unlike in D, Logical (boolean) operations only accept Logical elements true/false (called TRUE/FALSE on implementation side for obvious reason):
enum TRUE = new DElement(true);
enum FALSE = new DElement(false);
So, I thought I could write those operations by comparing pointers directly, eg:
Element not (Element operand) {
// checks type
operand.checkLogical()
return (operand == TRUE) ? FALSE : TRUE;
}
...
assert ( not(TRUE) == FALSE );
This fails! It even fails "doubly"...
When I call not(TRUE), TRUE (the pointer) inside the func is not equal to the global constant. Thus, not always returns FALSE. And in fact this is also wrong, because I have the same problem on the return value as well: the FALSE returned is not equal to the global FALSE.
But the pointed structs are ok. Each one holds a D boolean of the correct value (a member called 'logical'). Thus, the following succeeds:
Element not (Element operand) {
// checks type & returns the 'logical' member
auto log = operand.checkLogical();
return (log) ? FALSE : TRUE;
}
...
assert ( not(TRUE).logical == false );
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?
It is not a serious problem since the workaround is easy and not very costly. But I wish to understand why I cannot operate on constant 'identity'. As said above, this must a trivial issue I simply cannot guess...
Thank you,
Denis
--
_________________
vita es estrany
spir.wikidot.com
|
March 01, 2011 Re: comparing pointers passed to and returned from funcs | ||||
---|---|---|---|---|
| ||||
Posted in reply to spir | 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 |
March 01, 2011 Re: comparing pointers passed to and returned from funcs | ||||
---|---|---|---|---|
| ||||
Posted in reply to bearophile | This seems to work: import core.stdc.stdio: printf; struct Foo { bool b; this(bool b_) { this.b = b_; } } const(Foo)* TRUE, FALSE; static this() { TRUE = new const(Foo)(true); FALSE = new const(Foo)(false); } const(Foo)* not(const(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))); } Bye, bearophile |
March 01, 2011 Re: comparing pointers passed to and returned from funcs | ||||
---|---|---|---|---|
| ||||
Posted in reply to bearophile | http://d.puremagic.com/issues/show_bug.cgi?id=5678 |
March 01, 2011 Re: comparing pointers passed to and returned from funcs | ||||
---|---|---|---|---|
| ||||
Posted in reply to bearophile | On 3/1/11 3:00 PM, bearophile wrote:
> const(Foo)* TRUE, FALSE;
I'd remove those parens; you don't want people modifying TRUE or FALSE.
|
March 02, 2011 Re: comparing pointers passed to and returned from funcs | ||||
---|---|---|---|---|
| ||||
Posted in reply to Bekenn | Bekenn:
> I'd remove those parens; you don't want people modifying TRUE or FALSE.
Please, show me working code that implements your idea :-)
Bye,
bearophile
|
March 02, 2011 Re: comparing pointers passed to and returned from funcs | ||||
---|---|---|---|---|
| ||||
Posted in reply to bearophile | On 3/1/11 4:12 PM, bearophile wrote:
> Bekenn:
>
>> I'd remove those parens; you don't want people modifying TRUE or FALSE.
>
> Please, show me working code that implements your idea :-)
Touche. I'll have to test that out once I get back from work...
|
March 02, 2011 Re: comparing pointers passed to and returned from funcs | ||||
---|---|---|---|---|
| ||||
Posted in reply to Bekenn | Bekenn:
> Touche. I'll have to test that out once I get back from work...
Sorry for that answer of mine, we are here to learn and cooperate, not to fight :-) It's just I sometimes have problems with const things in D, and sometimes DMD has problems with const things.
Bye,
bearophile
|
March 02, 2011 Re: comparing pointers passed to and returned from funcs | ||||
---|---|---|---|---|
| ||||
Posted in reply to bearophile | On 3/1/11 5:31 PM, bearophile wrote:
> Bekenn:
>
>> Touche. I'll have to test that out once I get back from work...
>
> Sorry for that answer of mine, we are here to learn and cooperate, not to fight :-) It's just I sometimes have problems with const things in D, and sometimes DMD has problems with const things.
Hey, no problem; I thought it was funny...
|
March 02, 2011 Re: comparing pointers passed to and returned from funcs | ||||
---|---|---|---|---|
| ||||
Posted in reply to bearophile | On 3/1/2011 4:12 PM, bearophile wrote:
> Bekenn:
>
>> I'd remove those parens; you don't want people modifying TRUE or FALSE.
>
> Please, show me working code that implements your idea :-)
>
> Bye,
> bearophile
Here you go; I only changed the one line. Compiles and works just fine in dmd 2.051.
const Foo* TRUE, FALSE;
instead of
const(Foo)* TRUE, FALSE;
|
Copyright © 1999-2021 by the D Language Foundation