March 12, 2014 Re: Restriction on interface function types | ||||
---|---|---|---|---|
| ||||
Posted in reply to Steve Teale | On Wed, 12 Mar 2014 09:34:32 -0400, Steve Teale <steve.teale@britseyeview.com> wrote:
> On Wednesday, 12 March 2014 at 13:12:20 UTC, Steven Schveighoffer wrote:
>> On Wed, 12 Mar 2014 09:05:05 -0400, Steve Teale <steve.teale@britseyeview.com> wrote:
>
>> How is the compiler to build it's one copy of bad? Should x be typed as A or B? Or something not even seen in this module that could derive from I?
>>
>> -Steve
>
> Let's take bad() away, and instead:
>
> class A : I
> {
> A myType() { return cast(A)null;}
> final void foo();
> }
>
> class B : I
> {
> B myType() {return cast(B) null;}
> final void bar();
> }
>
> void main()
> {
> I[] arr = [new A, new B];
> foreach(i; arr) { (cast(typeof(i.myType()) i).foo() }
> }
>
> myType() is a virtual function, so calling it through the interface type should get the correct version right?, and then the cast should cause a call to A or B.
The type cannot be determined at runtime, it's a static language.
foreach(i; arr) { typeof(i.myType()) x = cast(i.myType()) i; x.foo();}
What is typeof(x)? It needs to be decided at compile time.
-Steve
|
March 12, 2014 Re: Restriction on interface function types | ||||
---|---|---|---|---|
| ||||
Posted in reply to Steve Teale | On Wednesday, 12 March 2014 at 13:34:33 UTC, Steve Teale wrote:
> On Wednesday, 12 March 2014 at 13:12:20 UTC, Steven Schveighoffer wrote:
>> On Wed, 12 Mar 2014 09:05:05 -0400, Steve Teale <steve.teale@britseyeview.com> wrote:
>
>> How is the compiler to build it's one copy of bad? Should x be typed as A or B? Or something not even seen in this module that could derive from I?
>>
>> -Steve
>
> Let's take bad() away, and instead:
>
> class A : I
> {
> A myType() { return cast(A)null;}
> final void foo();
> }
>
> class B : I
> {
> B myType() {return cast(B) null;}
> final void bar();
> }
>
> void main()
> {
> I[] arr = [new A, new B];
> foreach(i; arr) { (cast(typeof(i.myType()) i).foo() }
> }
>
> myType() is a virtual function, so calling it through the interface type should get the correct version right?, and then the cast should cause a call to A or B.
It will *call* the correct version, but the signature used will still statically be the interface's signature.
It can make a difference when you *statically* know you are in a derived type:
I i = new A();
A a = new A();
I ii = i.myType();
A aa = a.myType();
Here, the call to "myType", in both cases, will "runtime" resolve to A.myType().
*However*, the static type used to return the value, will not be the same.
|
March 12, 2014 Re: Restriction on interface function types | ||||
---|---|---|---|---|
| ||||
Posted in reply to Steven Schveighoffer | On Wednesday, 12 March 2014 at 13:45:30 UTC, Steven Schveighoffer wrote:
> What is typeof(x)? It needs to be decided at compile time.
>
> -Steve
OK, squirm, squirm - I misunderstood the examples for typeof.
Will you take a look at my last post on d.learn please. What I describe there is the motivation for my squirming. Can you suggest a compile-time way of telling ControlSet what class it is targeting at the point where an instance of it is declared?
Sorry
Steve
|
March 12, 2014 Re: Restriction on interface function types | ||||
---|---|---|---|---|
| ||||
Posted in reply to monarch_dodra | On Wed, 12 Mar 2014 09:51:32 -0400, monarch_dodra <monarchdodra@gmail.com> wrote: > On Wednesday, 12 March 2014 at 13:34:33 UTC, Steve Teale wrote: >> void main() >> { >> I[] arr = [new A, new B]; >> foreach(i; arr) { (cast(typeof(i.myType()) i).foo() } >> } >> >> myType() is a virtual function, so calling it through the interface type should get the correct version right?, and then the cast should cause a call to A or B. > > It will *call* the correct version, but the signature used will still statically be the interface's signature. There is no foo in the interface definition. The code is invalid, as is the idea you can declare variables based on a runtime type definition. -Steve |
March 12, 2014 Re: Restriction on interface function types | ||||
---|---|---|---|---|
| ||||
Posted in reply to Steve Teale | On Wed, 12 Mar 2014 09:54:00 -0400, Steve Teale <steve.teale@britseyeview.com> wrote:
> On Wednesday, 12 March 2014 at 13:45:30 UTC, Steven Schveighoffer wrote:
>
>> What is typeof(x)? It needs to be decided at compile time.
>>
>> -Steve
>
> OK, squirm, squirm - I misunderstood the examples for typeof.
>
> Will you take a look at my last post on d.learn please. What I describe there is the motivation for my squirming. Can you suggest a compile-time way of telling ControlSet what class it is targeting at the point where an instance of it is declared?
I saw that, but I think what you encountered was a bug in the compiler or differently-generated vtables. I think you should focus on trying to identify and fix the bug rather than trying to exploit a workaround.
One thing to try is re-compiling all your code. Any changes in vtables will mess up the linkage. If the compiler thinks your function to call is in index 2 in one compilation, but it's in index 3 in another, bad things will happen :)
-Steve
|
March 12, 2014 Re: Restriction on interface function types | ||||
---|---|---|---|---|
| ||||
Posted in reply to Steven Schveighoffer | On Wednesday, 12 March 2014 at 13:55:35 UTC, Steven Schveighoffer wrote: > On Wed, 12 Mar 2014 09:51:32 -0400, monarch_dodra <monarchdodra@gmail.com> wrote: > >> On Wednesday, 12 March 2014 at 13:34:33 UTC, Steve Teale wrote: > >>> void main() >>> { >>> I[] arr = [new A, new B]; >>> foreach(i; arr) { (cast(typeof(i.myType()) i).foo() } >>> } >>> >>> myType() is a virtual function, so calling it through the interface type should get the correct version right?, and then the cast should cause a call to A or B. >> >> It will *call* the correct version, but the signature used will still statically be the interface's signature. > > There is no foo in the interface definition. I meant call relative to "myType()". I can see how that was not clear actually. Sorry. > The code is invalid, as is the idea you can declare variables based on a runtime type definition. Yup. |
March 12, 2014 Re: Restriction on interface function types | ||||
---|---|---|---|---|
| ||||
Posted in reply to Steven Schveighoffer | On Wednesday, 12 March 2014 at 14:28:02 UTC, Steven Schveighoffer wrote:
> > I saw that, but I think what you encountered was a bug in the
> compiler or differently-generated vtables. I think you should focus on trying to identify and fix the bug rather than trying to exploit a workaround.
>
> One thing to try is re-compiling all your code. Any changes in vtables will mess up the linkage. If the compiler thinks your function to call is in index 2 in one compilation, but it's in index 3 in another, bad things will happen :)
>
Steve,
Recompilation has been frequent, and the makefile for the plugin refers to the sources for the app, and is otherwise just a single source file, so I don't think it is that.
My primary suspicion is that I am linking both the plugin and the app using the static gtkd-2 library. I believe the next step is to link both against a shared library version of gtkd-2. So far, I've had no success in building that. If the library code has static module constructors/destructors, or some such alternative down at the GTK+3 OOP C level, that uses a distinct text or data segment or something, then I can understand that I might well be hosed.
It's also noteworthy that I can't use an interface as a 'base class' for the plugin, even though the system should work with quite a limited set of methods. That works to the extent that methods that don't access data work OK, but if they do, the edifice comes tumbling down.
I'll have to brush up my command-line GDB skills to get much further - something I'm not looking forward to. Last time I did it was pre Iain Bucklaw when I was trying to sort out crashes in GDC.
The ability to dynamically load D shared libraries into a D program is something that's been way up my wish list since about 2006. Seems like there's some way to go yet. Even further for Windows, where we probably need a new linker!
At present, the app seems to be working pretty well with a plugin, as I have special cased the calls to host.onCSNotify() etc to apply the cast when the target is my main base class. Other uses will generally be entirely local to a plugin. So it might just stay like that for a while until I break it again.
Thanks
Steve
|
March 12, 2014 Re: Restriction on interface function types | ||||
---|---|---|---|---|
| ||||
Posted in reply to Steve Teale | On 12 March 2014 18:17, Steve Teale <steve.teale@britseyeview.com> wrote:
> On Wednesday, 12 March 2014 at 14:28:02 UTC, Steven Schveighoffer wrote:
>>
>> > I saw that, but I think what you encountered was a bug in the
>> compiler or differently-generated vtables. I think you should focus on trying to identify and fix the bug rather than trying to exploit a workaround.
>>
>> One thing to try is re-compiling all your code. Any changes in vtables
>> will mess up the linkage. If the compiler thinks your function to call is in
>> index 2 in one compilation, but it's in index 3 in another, bad things will
>> happen :)
>>
> Steve,
>
> Recompilation has been frequent, and the makefile for the plugin refers to the sources for the app, and is otherwise just a single source file, so I don't think it is that.
>
> My primary suspicion is that I am linking both the plugin and the app using the static gtkd-2 library. I believe the next step is to link both against a shared library version of gtkd-2. So far, I've had no success in building that. If the library code has static module constructors/destructors, or some such alternative down at the GTK+3 OOP C level, that uses a distinct text or data segment or something, then I can understand that I might well be hosed.
>
> It's also noteworthy that I can't use an interface as a 'base class' for the plugin, even though the system should work with quite a limited set of methods. That works to the extent that methods that don't access data work OK, but if they do, the edifice comes tumbling down.
>
> I'll have to brush up my command-line GDB skills to get much further - something I'm not looking forward to. Last time I did it was pre Iain Bucklaw when I was trying to sort out crashes in GDC.
>
My GDB work is yet to be fully released into the wild, but it's looking as a good solid base from where I'm testing.
|
March 12, 2014 Re: Restriction on interface function types | ||||
---|---|---|---|---|
| ||||
Posted in reply to Steve Teale | On Wednesday, 12 March 2014 at 10:57:10 UTC, Steve Teale wrote: > interface I > { > auto myType(); > } > > class A: I > { > auto myType() { return cast(A) null; } > } > > void main() > { > I x = getSomeI(); > typeof(x.myType()) y; > } Check out: http://forum.dlang.org/thread/ljqbcbitfptxqjauppte@forum.dlang.org / http://dpaste.dzfl.pl/6c90ca418996 It does what you want. As mentioned, you can't quite do this at compile time because the types must be known(or else just use object or a void *). You can, though do this at runtime: interface I { I myType(); // can return anything that derives from I } class A : I { final A _myType() { return cast(A) null; } //mixin(AbstractToInterface!(A, I, A)); // (won't work as is because only return type of myType will be different. Need to use different names) // The mixin would create the following function if slightly modified I myType() { return _myType; } } void main() { I x = getSomeI(); typeof(x._myType()) y1; typeof(x.myType()) y2; typeof(cast(Object)x.myType()) y; } y1 = y2 = I, y = A. (cast(Object) has to do with the weird way D handles interface types) Note, that this code works in that if a new class B is created, it can return it's type: class B : I { final B _myType() { return cast(B) null; } I myType() { return _myType; } } If getSomeI() returns B then y = B. Of course it's way easier just to do typeof(cast(Object)x) y; unless you want to potentially return different objects. |
March 12, 2014 Re: Restriction on interface function types | ||||
---|---|---|---|---|
| ||||
Posted in reply to Steven Schveighoffer | On Wednesday, 12 March 2014 at 11:56:43 UTC, Steven Schveighoffer wrote: > What you want simply isn't possible. An interface binds at runtime, and you need to declare types at compile-time. You can't use an interface method to define the type of y. Here's the method that is used in Phobos: http://forum.dlang.org/thread/yagdbyegdkibhaqlbyid@forum.dlang.org#post-zkdhdiszjklaepgkbxpj:40forum.dlang.org |
Copyright © 1999-2021 by the D Language Foundation