digitalmars.D.bugs - === No Damn Good
- teqDruid (28/28) Jan 12 2005 I'm relatively sure that this code should run...
- Thomas Kuehne (12/40) Jan 12 2005 -----BEGIN PGP SIGNED MESSAGE-----
- teqDruid (6/55) Jan 12 2005 Thanks. That was fast! I just hope this doesn't become one of those tes...
- Ben Hinkle (5/7) Jan 12 2005 As another work-around it looks like it works if you do
- Ben Hinkle (3/8) Jan 12 2005 whoops - I read the wrong line number. My code above isn't a workaround.
- teqDruid (17/26) Jan 12 2005 So here's the code that doesn't work properly:
- Ben Hinkle (4/12) Jan 12 2005 how about
- teqDruid (6/20) Jan 12 2005 D'uh... the worked. There are still some other places in the library
- kris (8/34) Jan 12 2005 The problem with such casts is that they're of the dynamic variety.
- Burton Radons (46/61) Jan 31 2005 An object supplied by a foreign-language DOM won't have an Object
- Ben Hinkle (8/54) Jan 31 2005 What do DOMs and ORBs have to do with how D handles interfaces? I don't ...
- Burton Radons (29/45) Jan 31 2005 Whoops, I assumed that you could cast a foreign language object
I'm relatively sure that this code should run... interface I { I parent(); void parent(I i); void addChild(I i); } interface J : I {} class A : I { private I myParent; void addChild(I i) { i.parent = this; } I parent() { return myParent; } void parent(I parent) { myParent = parent;} } class B : A, J {} void main() { J a = new B; J b = new B; a.addChild(b); assert(cast(J)b.parent === a); // This works assert(b.parent === a); // So this one should too.. it doesn't } This one took me a LONG time to boil down to this, and affects me in a pretty HUGE way... Walter, I'd appreciate it if this one is resolved soon. I'm running DMD 0.110 on Linux. John
Jan 12 2005
-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 Added to DStress as http://dstress.kuehne.cn/run/opIdentity_01.d http://dstress.kuehne.cn/run/opIdentity_02.d Thomas teqDruid schrieb am Wed, 12 Jan 2005 08:20:54 -0500:I'm relatively sure that this code should run... interface I { I parent(); void parent(I i); void addChild(I i); } interface J : I {} class A : I { private I myParent; void addChild(I i) { i.parent = this; } I parent() { return myParent; } void parent(I parent) { myParent = parent;} } class B : A, J {} void main() { J a = new B; J b = new B; a.addChild(b); assert(cast(J)b.parent === a); // This works assert(b.parent === a); // So this one should too.. it doesn't } This one took me a LONG time to boil down to this, and affects me in a pretty HUGE way... Walter, I'd appreciate it if this one is resolved soon. I'm running DMD 0.110 on Linux. John-----BEGIN PGP SIGNATURE----- iD8DBQFB5TBq3w+/yD4P9tIRAoHNAJ9aBDuCqnVpj4GQHnRTT694EzvQRgCePYhg SuJbe6p9ydxEDElgJuXb134= =mh8D -----END PGP SIGNATURE-----
Jan 12 2005
Thanks. That was fast! I just hope this doesn't become one of those tests on there that hasn't been touched in awhile. It basically prohibits my DOM implementation from working correctly. BTW, you've got a typo on the module identifier in the second one. John On Wed, 12 Jan 2005 15:12:59 +0100, Thomas Kuehne wrote:-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 Added to DStress as http://dstress.kuehne.cn/run/opIdentity_01.d http://dstress.kuehne.cn/run/opIdentity_02.d Thomas teqDruid schrieb am Wed, 12 Jan 2005 08:20:54 -0500:I'm relatively sure that this code should run... interface I { I parent(); void parent(I i); void addChild(I i); } interface J : I {} class A : I { private I myParent; void addChild(I i) { i.parent = this; } I parent() { return myParent; } void parent(I parent) { myParent = parent;} } class B : A, J {} void main() { J a = new B; J b = new B; a.addChild(b); assert(cast(J)b.parent === a); // This works assert(b.parent === a); // So this one should too.. it doesn't } This one took me a LONG time to boil down to this, and affects me in a pretty HUGE way... Walter, I'd appreciate it if this one is resolved soon. I'm running DMD 0.110 on Linux. John-----BEGIN PGP SIGNATURE----- iD8DBQFB5TBq3w+/yD4P9tIRAoHNAJ9aBDuCqnVpj4GQHnRTT694EzvQRgCePYhg SuJbe6p9ydxEDElgJuXb134= =mh8D -----END PGP SIGNATURE-----
Jan 12 2005
assert(cast(J)b.parent === a); // This works assert(b.parent === a); // So this one should too.. it doesn'tAs another work-around it looks like it works if you do I x = b.parent; assert(x === a); Why does it prohibit your DOM code form working? Can't you use one of the workarounds?
Jan 12 2005
"Ben Hinkle" <bhinkle mathworks.com> wrote in message news:cs3g39$2219$1 digitaldaemon.com...whoops - I read the wrong line number. My code above isn't a workaround.assert(cast(J)b.parent === a); // This works assert(b.parent === a); // So this one should too.. it doesn'tAs another work-around it looks like it works if you do I x = b.parent; assert(x === a);
Jan 12 2005
So here's the code that doesn't work properly: private Node[] list; ulong getPos(Node node) { foreach (int i, Node n; list) if (n === node) return i; return -1; } In this case, Node is an interface analagous to I. The problem is that the pointer in the list isn't kosher for === comparisons to other Nodes, so the function that adds it to the list has to be modified. This function, however, also uses the Node interface. The only way (I see) to get around this bug is by forcing the programmer to interface with the library in a bizarre manner... which I've been unsucessfully trying to do. I don't fully understand the bug, or why it is occurring... John On Wed, 12 Jan 2005 10:35:04 -0500, Ben Hinkle wrote:assert(cast(J)b.parent === a); // This works assert(b.parent === a); // So this one should too.. it doesn'tAs another work-around it looks like it works if you do I x = b.parent; assert(x === a); Why does it prohibit your DOM code form working? Can't you use one of the workarounds?
Jan 12 2005
"teqDruid" <me teqdruid.com> wrote in message news:pan.2005.01.12.15.44.42.756023 teqdruid.com...So here's the code that doesn't work properly: private Node[] list; ulong getPos(Node node) { foreach (int i, Node n; list) if (n === node) return i; return -1; }how about if (cast(Object)n === cast(Object)node)
Jan 12 2005
D'uh... the worked. There are still some other places in the library where I can't do a cast, and the programmer interfacing with the library will have to do it, but this does reduce the problem severity a bit. Thanks, John On Wed, 12 Jan 2005 15:41:34 -0500, Ben Hinkle wrote:"teqDruid" <me teqdruid.com> wrote in message news:pan.2005.01.12.15.44.42.756023 teqdruid.com...So here's the code that doesn't work properly: private Node[] list; ulong getPos(Node node) { foreach (int i, Node n; list) if (n === node) return i; return -1; }how about if (cast(Object)n === cast(Object)node)
Jan 12 2005
teqDruid wrote:D'uh... the worked. There are still some other places in the library where I can't do a cast, and the programmer interfacing with the library will have to do it, but this does reduce the problem severity a bit. Thanks, John On Wed, 12 Jan 2005 15:41:34 -0500, Ben Hinkle wrote:The problem with such casts is that they're of the dynamic variety. Based on prior experience, the dynamic cast will take ~5 times longer to execute than the rest of each loop pass (in this case), and there's two such casts required ... It's actually faster to dispatch to a class specific opEquals(), and do a single dynamic cast there instead. Of course, none of this is what one might call 'intuitive'"teqDruid" <me teqdruid.com> wrote in message news:pan.2005.01.12.15.44.42.756023 teqdruid.com...So here's the code that doesn't work properly: private Node[] list; ulong getPos(Node node) { foreach (int i, Node n; list) if (n === node) return i; return -1; }how about if (cast(Object)n === cast(Object)node)
Jan 12 2005
Ben Hinkle wrote:"teqDruid" <me teqdruid.com> wrote in message news:pan.2005.01.12.15.44.42.756023 teqdruid.com...An object supplied by a foreign-language DOM won't have an Object casting, so those casts will return null. A CORBA ORB which only works through networking should be safe, but one which interfaces with foreign-language ORBs through native bindings won't be. It's not the right hack-around. I'll illustrate what's happening. Take this tree: interface IA { void call (IA); } interface IB : IA { } class CA : IA { void call (IA) { ... } } class CB : CA, IB { } The layout of the classes looks somewhat like this: struct Object_layout { VTable *vtable; void *handle; } struct CA_layout { Object_layout Object_data; VTable *IA_vtable; } struct CB_layout { CA_layout CA_data; VTable *IA_vtable; VTable *IB_vtable; } So there are multiple pointers to the IA vtable within an instance of CB. Casting to a solid type, like Object, works because there's only one of those, but if you keep them as interfaces the runtime can get to either vtable depending upon which course it uses. What I did is add a hack method called "self" to Node which just returns "this". "Node.isSameNode" has this implementation: boolean isSameNode (Node other) { return this === other || (other !== null && this === other.self ()); } isSameNode should always be used by the user anyway because there might be multiple proxies to the same object. CORBA has a method in its Object class which tests for equivalent references, but unfortunately DOM is not as tightly bound to CORBA as would be preferable (hence the lack of use of the string type which allows the implementation to use any local encoding, and the stupid forcing of UTF-16). Regarding time cost, "===" is a costly operation anyway.So here's the code that doesn't work properly: private Node[] list; ulong getPos(Node node) { foreach (int i, Node n; list) if (n === node) return i; return -1; }how about if (cast(Object)n === cast(Object)node)
Jan 31 2005
What do DOMs and ORBs have to do with how D handles interfaces? I don't see the relevance. I thought one can cast any instance of a class to Object so I'm confused about when cast(Object)node can fail.how about if (cast(Object)n === cast(Object)node)An object supplied by a foreign-language DOM won't have an Object casting, so those casts will return null. A CORBA ORB which only works through networking should be safe, but one which interfaces with foreign-language ORBs through native bindings won't be. It's not the right hack-around.I'll illustrate what's happening. Take this tree: interface IA { void call (IA); } interface IB : IA { } class CA : IA { void call (IA) { ... } } class CB : CA, IB { } The layout of the classes looks somewhat like this: struct Object_layout { VTable *vtable; void *handle; } struct CA_layout { Object_layout Object_data; VTable *IA_vtable; } struct CB_layout { CA_layout CA_data; VTable *IA_vtable; VTable *IB_vtable; } So there are multiple pointers to the IA vtable within an instance of CB. Casting to a solid type, like Object, works because there's only one of those, but if you keep them as interfaces the runtime can get to either vtable depending upon which course it uses.I agree. That is why casting to Object provides a "unique id" so that === will work. It normalizes the different interface references to the object.What I did is add a hack method called "self" to Node which just returns "this". "Node.isSameNode" has this implementation: boolean isSameNode (Node other) { return this === other || (other !== null && this === other.self ()); } isSameNode should always be used by the user anyway because there might be multiple proxies to the same object. CORBA has a method in its Object class which tests for equivalent references, but unfortunately DOM is not as tightly bound to CORBA as would be preferable (hence the lack of use of the string type which allows the implementation to use any local encoding, and the stupid forcing of UTF-16).sounds like isSameNode is what opEquals should do (except for the argument type being Object vs Node).Regarding time cost, "===" is a costly operation anyway.=== is costly? It should be a pointer comparison.
Jan 31 2005
Ben Hinkle wrote:Whoops, I assumed that you could cast a foreign language object reference (an object allocated by a foreign language), and I realise that's not very likely. More likely is that if you attempt to cast a foreign language object, either implicitly, explicitly, or by using === when the objects don't have the same first pointer in the vtable, it will always SIGSEGV, because casting requires use of ClassInfo which won't be the same. What a pain. But even if we could cast foreign language object references, you still won't be able to cast to Object, because foreign language objects won't have Object in their base. Object will be the root class of an object created by D only.What do DOMs and ORBs have to do with how D handles interfaces? I don't see the relevance. I thought one can cast any instance of a class to Object so I'm confused about when cast(Object)node can fail.how about if (cast(Object)n === cast(Object)node)An object supplied by a foreign-language DOM won't have an Object casting, so those casts will return null. A CORBA ORB which only works through networking should be safe, but one which interfaces with foreign-language ORBs through native bindings won't be. It's not the right hack-around.Exploring the problem with RTTI, I think there's just a bug in ===; I don't see any trace of shadow interfaces. I was wrong about the source of the problem. It might be because using .classinfo when an object is posing as an interface produces the interface's ClassInfo rather than the real one. Here's an example: interface A { } class B : A { } void main () { B b = new B (); A a = b; printf ("%.*s %.*s\n", b.classinfo.name, a.classinfo.name); } This prints "B A", when it should be "B B". I think this is a bug, because if "A" is a class instead of an interface, it produces "B B" as it should.So there are multiple pointers to the IA vtable within an instance of CB. Casting to a solid type, like Object, works because there's only one of those, but if you keep them as interfaces the runtime can get to either vtable depending upon which course it uses.
Jan 31 2005