Thread overview | |||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
April 05, 2004 [BUG] casting Interface to class-instance generates bogus code | ||||
---|---|---|---|---|
| ||||
I have a concrete-class that implements a generic interface. On occasion, said interface needs to be upcast to the concrete-class to access specialized functionality. Check out the cast(SocketConduit) code below ... it explicitly sets the lValue to zero. Good Grief ... 112: char[] getRemoteAddress (IConduit conduit) 00403290 enter 0Ch,0 00403294 mov dword ptr [ebp-0Ch],eax 113: { 114: SocketConduit socket = cast(SocketConduit) conduit; 00403297 xor eax,eax 00403299 mov dword ptr [socket],eax |
April 05, 2004 Re: [BUG] casting Interface to class-instance generates bogus code | ||||
---|---|---|---|---|
| ||||
Posted in reply to Kris | On a hunch, I thought I'd try the old (void *) trick. As you can see below, it actually persuaded the compiler into doing the right thing. Oh well; onto the next showstopper. 112: char[] getRemoteAddress (IConduit conduit) 00403290 enter 0Ch,0 00403294 mov dword ptr [ebp-0Ch],eax 113: { 114: SocketConduit socket = cast(SocketConduit) cast(void *) conduit; 00403297 mov eax,dword ptr [conduit] 0040329A mov dword ptr [socket],eax |
April 05, 2004 Re: [BUG] casting Interface to class-instance generates bogus code | ||||
---|---|---|---|---|
| ||||
Posted in reply to Kris | On Sun, 04 Apr 2004 19:25:18 -0800, Kris wrote:
> On a hunch, I thought I'd try the old (void *) trick.
>
> 114: SocketConduit socket = cast(SocketConduit) cast(void
> *) conduit;
great. I had the same problem before and my work
around was... so complex that I even don't remember.
Ant
|
April 05, 2004 Re: [BUG] casting Interface to class-instance generates bogus code | ||||
---|---|---|---|---|
| ||||
Posted in reply to Ant | Oops; I'm afraid I jumped the gun on that one. The (void *) cast drops some
of the vTable offsets (or something), so it end's up calling the wrong
place. I'm not sure if that's better or worse than before :-)
I was just going through the code to see if I could avoid the interface altogether, and I'm afraid that would make the whole system specific to SocketConduit only. Hence that is simply not an option.
If you can recall what you did to resolve your issue? I'd really appreciate any help Ant.
Cheers,
- Kris
> Ant wrote:
> great. I had the same problem before and my work
> around was... so complex that I even don't remember.
>
> Ant
>
|
April 05, 2004 Re: [BUG] casting Interface to class-instance generates bogus code | ||||
---|---|---|---|---|
| ||||
Posted in reply to Kris | On Sun, 04 Apr 2004 19:48:27 -0800, Kris wrote:
> Oops; I'm afraid I jumped the gun on that one. The (void *) cast drops some
> of the vTable offsets (or something), so it end's up calling the wrong
> place. I'm not sure if that's better or worse than before :-)
>
> I was just going through the code to see if I could avoid the interface altogether, and I'm afraid that would make the whole system specific to SocketConduit only. Hence that is simply not an option.
>
> If you can recall what you did to resolve your issue? I'd really appreciate any help Ant.
>
> Cheers,
>
> - Kris
Sorry, I don't think I can help, I really don't
remember but I think I redesign something
and I'm avoiding it since.
I believe this is covered on Burton Radons
interface and inheritance bug report let's
hope Walter is looking at that.
Ant
|
April 05, 2004 Re: [BUG] casting Interface to class-instance generates bogus code | ||||
---|---|---|---|---|
| ||||
Posted in reply to Kris | The problem here is that all an interface is, when implemented, is a pointer to a vtbl[]. There's no way the runtime can tell where it came from, so there is no way to upcast it. The way to deal with this is to add a member function to the interface that is equivalent to the 'ClassFactory' function in COM programming. Then, in the implementation of that function, which does know the object type enclosing the interface, the cast can be done. interface IConduit { SocketConduit isSocketConduit(); } class SocketConduit : IConduit { SocketConduit isSocketConduit() { return this; } } char[] getRemoteAddress(IConduit conduit) { SocketConduit socket = conduit.isSocketConduit(); } "Kris" <someidiot@earthlink.dot.dot.dot.net> wrote in message news:c4qi35$24f8$1@digitaldaemon.com... > I have a concrete-class that implements a generic interface. On occasion, said interface needs to be upcast to the concrete-class to access specialized functionality. Check out the cast(SocketConduit) code below ... > it explicitly sets the lValue to zero. Good Grief ... > > 112: char[] getRemoteAddress (IConduit conduit) > 00403290 enter 0Ch,0 > 00403294 mov dword ptr [ebp-0Ch],eax > 113: { > 114: SocketConduit socket = cast(SocketConduit) conduit; > 00403297 xor eax,eax > 00403299 mov dword ptr [socket],eax > > > |
April 05, 2004 Re: [BUG] casting Interface to class-instance generates bogus code | ||||
---|---|---|---|---|
| ||||
Posted in reply to Walter | Thank-you Walter. I truly appreciate your help on this. BTW, is this the expected long-term solution? If so (and I don't think it should be <g>) the compiler really needs to toss an error, rather than emitting grossly unjust access-violators ... - Kris "Walter" <walter@digitalmars.com> wrote in message news:c4sk0f$2eon$1@digitaldaemon.com... > The problem here is that all an interface is, when implemented, is a pointer > to a vtbl[]. There's no way the runtime can tell where it came from, so there is no way to upcast it. > > The way to deal with this is to add a member function to the interface that > is equivalent to the 'ClassFactory' function in COM programming. Then, in the implementation of that function, which does know the object type enclosing the interface, the cast can be done. > |
April 05, 2004 Re: [BUG] casting Interface to class-instance generates bogus code | ||||
---|---|---|---|---|
| ||||
Posted in reply to Walter | Whoops -- I meant to add why I feel this should not be the accepted procedure: The solution provided works fine to skirt the issue at hand, but the methodology requires that the base-class (or base-interface) is pre-configured to know about *all possible derivations* (subclasses). That, is simply unrealistic. - Kris "Walter" <walter@digitalmars.com> wrote in message news:c4sk0f$2eon$1@digitaldaemon.com... > The problem here is that all an interface is, when implemented, is a pointer > to a vtbl[]. There's no way the runtime can tell where it came from, so there is no way to upcast it. > > The way to deal with this is to add a member function to the interface that > is equivalent to the 'ClassFactory' function in COM programming. Then, in the implementation of that function, which does know the object type enclosing the interface, the cast can be done. >> |
April 05, 2004 Re: [BUG] casting Interface to class-instance generates bogus code | ||||
---|---|---|---|---|
| ||||
Posted in reply to Kris | Please forgive my gratuitous overuse of this NG ... Thinking about this a little more Walter, if the base-interface were to implement just the upcast to a concrete Object, then dynamic-casting should handle it from there. For example: interface IConduit { Object toObject(); } class SocketConduit : IConduit { Object toObject() { return this; } } char[] getRemoteAddress(IConduit conduit) { SocketConduit socket = cast(SocketConduit) conduit.toObject(); } This, at least, is extensible. Though I'm torn as to whether it's the right-thing-to-do <g> Note: one might be tempted to implement this instead as: interface IConduit { Conduit toConduit(); } ...assuming there were a base-class implementation for IConduit. However, that doesn't lend itself toward a sense of 'pattern' (let alone the potential "forward reference" issues that an Interfaces is handy for resolving). If, in fact, you were to decide the suggested approach is the long-term solution, then you might consider adding a hidden toObject() declaration to each interface, and the corresponding "return this;" implementation to each of the appropriate classes. If so, toObject() could thus become a property of any Interface. Not too sure about that attitude though. "Kris" <someidiot@earthlink.dot.dot.dot.net> wrote in message news:c4skns$2fu9$1@digitaldaemon.com... > The solution provided works fine to skirt the issue at hand, but the > methodology requires that the base-class (or base-interface) is > pre-configured to know about *all possible derivations* (subclasses). That, > is simply unrealistic. > |
April 05, 2004 Re: [BUG] casting Interface to class-instance generates bogus code | ||||
---|---|---|---|---|
| ||||
Posted in reply to Walter | Walter wrote:
> The problem here is that all an interface is, when implemented, is a pointer
> to a vtbl[]. There's no way the runtime can tell where it came from, so
> there is no way to upcast it.
"No way", as in "impossible", or in "no way" as in "not for 1.0"? ;)
Couldn't there be a virtual function "Object __getObject()" that is automatically generated for all classes? Then the cast operator could simply call this function when casting an interface to an object. Seems like the only way to have the cast operator behave consistently.
Hauke
|
Copyright © 1999-2021 by the D Language Foundation