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