Identity of interfaces (or not)

Tomas Lindquist Olsen tomas at famolsen.dk
Tue Dec 2 07:28:01 PST 2008


Hi all.

I've spent that last weeks rewriting LDC's handling handling of struct/union/class/interface to 
match DMD, in terms of datalayout, ABI and correctness in general. It's done now, and seems to 
be working well, however, running DStress on the latest revision, a new regression showed up!

Test case:
http://dsource.org/projects/dstress/browser/run/opIdentity_01.d

Original NG post with issue:
http://www.digitalmars.com/pnews/read.php?server=news.digitalmars.com&group=digitalmars.D.bugs&artnum=2676

I've failed to find any replies to the thread so I'm unsure if this test is even valid.

I'll paste the test case from DStress here as well:

<code>
module dstress.run.opIdentity_01;
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 {
}
int main() {
     J a = new B;
     J b = new B;
     a.addChild(b);
     if(!(b.parent is a)){ // FAILS
         assert(0);
     }
     return 0;
}
</code>

Here's the problem. DMD and (now) LDC both compile this test fine, but it fails at runtime on 
the marked line.

The problem is that B has two vtables that implement the interface I. However, in A.addChild, 
i.parent get's the first one (introduced by A), and in main, it gets the second one (J , which 
derived from I). The identity check then fails because the pointers aren't the same, even 
though it's the same object in question.

The easiest way I can see to make this work, would be to disable static "downcasts" to 
interfaces, this way, in A.addChild, when 'this' is converted to I, it would have to look 
through the ClassInfo and would always use the same vtable for a single interface.

The other would be to change the ABI...

But, I'm not even sure if this is a bug or if D interfaces just work this way, I've not been 
able to find much information...

So is it a bug? Or is identity for interfaces simply not guaranteed to pass, even when it's the 
same Object in question?

Thanx
- Tomas



More information about the Digitalmars-d mailing list