digitalmars.D.bugs - Covariant returns for interfaces
- Sean Kelly (37/37) Oct 09 2004 I don't think this is a bug, but the inconsistency strikes me as a bit
- Ben Hinkle (16/59) Oct 09 2004 I assume it's because the cast from C to I is non-trivial while casting ...
-
Stewart Gordon
(9/17)
Oct 11 2004
- Ben Hinkle (14/37) Oct 11 2004 It is important when someone calls a function and expects an interface
- Stewart Gordon (27/50) Oct 11 2004 I think we're talking a bit at cross purposes.
- Ben Hinkle (12/62) Oct 11 2004 I see what you mean. It does seem wierd that an interface can't be
- Sean Kelly (3/9) Oct 11 2004 I was reporting the latter problem. Sorry for the confusion.
- Sean Kelly (37/48) Oct 11 2004 BTW, here's a test case that avoids the other issue:
- Sean Kelly (4/8) Oct 11 2004 Yup. I'd forgotten about this. If that's the way it has to be then tha...
I don't think this is a bug, but the inconsistency strikes me as a bit odd. Basically, covariant returns are allowed for class inheritance but not for interface inheritance. For example: This code works just fine, but if I change line A to: C getI() { return new C(); } then I get an error: "class C interface function I.getI isn't implemented." What I'm not sure of is whether this is how things *should* be. I want to say yes, but on one level it seems odd that covariant returns aren't allowed for interfaces. Sean
Oct 09 2004
Sean Kelly wrote:I don't think this is a bug, but the inconsistency strikes me as a bit odd. Basically, covariant returns are allowed for class inheritance but not for interface inheritance. For example: This code works just fine, but if I change line A to: C getI() { return new C(); } then I get an error: "class C interface function I.getI isn't implemented." What I'm not sure of is whether this is how things *should* be. I want to say yes, but on one level it seems odd that covariant returns aren't allowed for interfaces. SeanI assume it's because the cast from C to I is non-trivial while casting from a subclass to a superclass is trivial (ie - it doesn't generate any code). Try the following to see what I mean: interface A {}; class B:A {}; class C:B {}; int main() { B b = new B; A a = b; printf("%p %p\n",b,a); // not the same pointer C c = new C; b = c; printf("%p %p\n",b,c); // the same pointer return 0; }
Oct 09 2004
Ben Hinkle wrote:Sean Kelly wrote:<snip> I do. It's been reported already, along with a related problem that probably boils down to the same thing: http://www.digitalmars.com/drn-bin/wwwnews?digitalmars.D.bugs/1726I don't think this is a bug, but the inconsistency strikes me as a bit odd. Basically, covariant returns are allowed for class inheritance but not for interface inheritance. For example:I assume it's because the cast from C to I is non-trivial while casting from a subclass to a superclass is trivial (ie - it doesn't generate any code). Try the following to see what I mean:<snip> What would that have to do with anything? Stewart.
Oct 11 2004
Stewart Gordon wrote:Ben Hinkle wrote:It is important when someone calls a function and expects an interface pointer returned but gets an Object pointer. The caller starts dereferencing the bogus "interface pointer" and has random behavior. To put it another way take the OP's example and suppose C.getI could be declared as returning C. Then if one executed the line I ci = cast(I)c; I i = ci.getI(); // dynamic dispatch for I.getI will not return the right pointer. By declaring the return type as I there is an implicit cast at the end of C.getI to the interface which adjusts the pointer as my example code indicated. If the return type was C that adjustment wouldn't happen since there isn't any implicit cast to I. That would mean the ci.getI() call would think it was getting the interface pointer but sometimes gets the Object pointer instead.Sean Kelly wrote:<snip> I do. It's been reported already, along with a related problem that probably boils down to the same thing: http://www.digitalmars.com/drn-bin/wwwnews?digitalmars.D.bugs/1726I don't think this is a bug, but the inconsistency strikes me as a bit odd. Basically, covariant returns are allowed for class inheritance but not for interface inheritance. For example:I assume it's because the cast from C to I is non-trivial while casting from a subclass to a superclass is trivial (ie - it doesn't generate any code). Try the following to see what I mean:<snip> What would that have to do with anything?Stewart.
Oct 11 2004
Ben Hinkle wrote:Stewart Gordon wrote:<snip>Ben Hinkle wrote:I think we're talking a bit at cross purposes. The problem you're thinking of is that a method with an interface return type cannot be covariantly overridden with a class return type. OTOH, I was thinking of the problem that a method defined in an interface cannot be implemented with a covariant return type. The OP doesn't clarify which bug is being reported, since the example does both simultaneously. The OP's example would have equally failed if we'd defined interface I { B getB(); } instead. OTOH, your interpretation means that class B { abstract public I getI(); } class C : B { public C getI() { ... } } would fail. I'm not sure if I've tried this myself.It is important when someone calls a function and expects an interface pointer returned but gets an Object pointer. The caller starts dereferencing the bogus "interface pointer" and has random behavior.I assume it's because the cast from C to I is non-trivial while casting from a subclass to a superclass is trivial (ie - it doesn't generate any code). Try the following to see what I mean:<snip> What would that have to do with anything?To put it another way take the OP's example and suppose C.getI could be declared as returning C. Then if one executed the line I ci = cast(I)c; I i = ci.getI(); // dynamic dispatch for I.getI will not return the right pointer. By declaring the return type as I there is an implicit cast at the end of C.getI to the interface which adjusts the pointer as my example code indicated. If the return type was C that adjustment wouldn't happen since there isn't any implicit cast to I.<snip> You have a point. I can now guess that an interface pointer is a combination of an object pointer and a pointer to the interface's vtbl. I wonder if they can be implemented differently such that this problem doesn't exist.... Stewart.
Oct 11 2004
"Stewart Gordon" <smjg_1998 yahoo.com> wrote in message news:cke6id$1hkp$1 digitaldaemon.com...Ben Hinkle wrote:I see what you mean. It does seem wierd that an interface can't be implemented covariantly. I don't know if there is a technical reason for this.Stewart Gordon wrote:<snip>Ben Hinkle wrote:I think we're talking a bit at cross purposes. The problem you're thinking of is that a method with an interface return type cannot be covariantly overridden with a class return type. OTOH, I was thinking of the problem that a method defined in an interface cannot be implemented with a covariant return type. The OP doesn't clarify which bug is being reported, since the example does both simultaneously. The OP's example would have equally failed if we'd defined interface I { B getB(); } instead. OTOH, your interpretation means that class B { abstract public I getI(); } class C : B { public C getI() { ... } } would fail. I'm not sure if I've tried this myself.It is important when someone calls a function and expects an interface pointer returned but gets an Object pointer. The caller starts dereferencing the bogus "interface pointer" and has random behavior.I assume it's because the cast from C to I is non-trivial while casting from a subclass to a superclass is trivial (ie - it doesn't generate any code). Try the following to see what I mean:<snip> What would that have to do with anything?declaredTo put it another way take the OP's example and suppose C.getI could bethereas returning C. Then if one executed the line I ci = cast(I)c; I i = ci.getI(); // dynamic dispatch for I.getI will not return the right pointer. By declaring the return type as Itheis an implicit cast at the end of C.getI to the interface which adjustsI was thinking about that, too. I'm not a compiler writer so I don't know exactly how interfaces are implemented but there are probably a few possibilities. It would be nice to have objects and interfaces share the same pointer. It's probably not easy, though.pointer as my example code indicated. If the return type was C that adjustment wouldn't happen since there isn't any implicit cast to I.<snip> You have a point. I can now guess that an interface pointer is a combination of an object pointer and a pointer to the interface's vtbl. I wonder if they can be implemented differently such that this problem doesn't exist....Stewart.
Oct 11 2004
In article <cke6id$1hkp$1 digitaldaemon.com>, Stewart Gordon says...The problem you're thinking of is that a method with an interface return type cannot be covariantly overridden with a class return type. OTOH, I was thinking of the problem that a method defined in an interface cannot be implemented with a covariant return type. The OP doesn't clarify which bug is being reported, since the example does both simultaneously.I was reporting the latter problem. Sorry for the confusion. Sean
Oct 11 2004
In article <ckea98$1l8o$1 digitaldaemon.com>, Sean Kelly says...In article <cke6id$1hkp$1 digitaldaemon.com>, Stewart Gordon says...BTW, here's a test case that avoids the other issue: Error is: "test.d(20): class D interface function I.getI isn't implemented" Now in a sense I can understand the logic behind this--interfaces are kind of like a contract imposed on an implementation. But I still find it a bit odd that covariant returns works for inheritance from abstract base classes but not from interfaces. Not a big issue, but I figured it was worth mentioning. SeanThe problem you're thinking of is that a method with an interface return type cannot be covariantly overridden with a class return type. OTOH, I was thinking of the problem that a method defined in an interface cannot be implemented with a covariant return type. The OP doesn't clarify which bug is being reported, since the example does both simultaneously.I was reporting the latter problem. Sorry for the confusion.
Oct 11 2004
In article <cke6id$1hkp$1 digitaldaemon.com>, Stewart Gordon says...You have a point. I can now guess that an interface pointer is a combination of an object pointer and a pointer to the interface's vtbl. I wonder if they can be implemented differently such that this problem doesn't exist....Yup. I'd forgotten about this. If that's the way it has to be then that's fine, but it would be nice if it didn't... Sean
Oct 11 2004