Thread overview | ||||||||
---|---|---|---|---|---|---|---|---|
|
April 19, 2004 Virtual methods and class libraries | ||||
---|---|---|---|---|
| ||||
Hi, The D spec says: "All non-static non-private member functions are virtual. This may sound inefficient, but since the D compiler knows all of the class hierarchy when generating code, all functions that are not overridden can be optimized to be non-virtual." ... but I don't understand how this works when you wish to place objects into shared libraries. In this case, it might be the case that another library subclasses the class and therefore the compiler cannot know the entire class hierarchy. How is this supposed to work? I know D has no stable ABI, but this could be a serious problem for people wishing to split programs into multiple DSOS/DLLS. If this situation simply is not dealt with currently, a virtual keyword that forces a method to have a vtable entry may be a useful addition to the language. thanks -mike |
April 19, 2004 Re: Virtual methods and class libraries | ||||
---|---|---|---|---|
| ||||
Posted in reply to Mike Hearn | "Mike Hearn" <mike@navi.cx> wrote in message news:pan.2004.04.19.13.51.27.807711@navi.cx... > Hi, > > The D spec says: > > "All non-static non-private member functions are virtual. This may sound inefficient, but since the D compiler knows all of the class hierarchy when generating code, all functions that are not overridden can be optimized to be non-virtual." > > ... but I don't understand how this works when you wish to place objects into shared libraries. In this case, it might be the case that another library subclasses the class and therefore the compiler cannot know the entire class hierarchy. You're right. For those cases, a virtual call will be made. And, even if a non-virtual call can be made, the compiler still puts it in the vtbl[]. |
April 20, 2004 Re: Virtual methods and class libraries | ||||
---|---|---|---|---|
| ||||
Posted in reply to Walter | On Mon, 19 Apr 2004 16:51:50 -0700, Walter wrote:
>
> "Mike Hearn" <mike@navi.cx> wrote in message news:pan.2004.04.19.13.51.27.807711@navi.cx...
>> Hi,
>>
>> The D spec says:
>>
>> "All non-static non-private member functions are virtual. This may sound inefficient, but since the D compiler knows all of the class hierarchy when generating code, all functions that are not overridden can be optimized to be non-virtual."
>>
>> ... but I don't understand how this works when you wish to place objects into shared libraries. In this case, it might be the case that another library subclasses the class and therefore the compiler cannot know the entire class hierarchy.
>
> You're right. For those cases, a virtual call will be made. And, even if a non-virtual call can be made, the compiler still puts it in the vtbl[].
I still don't get it. The typical use case here would be writing a shared
library for e.g. a gui, where the app using the library typically derive
from classes in the library. Now, when building the library, how does the
compiler know that it has to make virtual calls, even though no class
in the library overrides the method, because some app code might
derive from the class and override the method?
|
April 20, 2004 Re: Virtual methods and class libraries | ||||
---|---|---|---|---|
| ||||
Posted in reply to Alexander Larsson | Alexander Larsson wrote:
> I still don't get it. The typical use case here would be writing a shared
> library for e.g. a gui, where the app using the library typically derive
> from classes in the library. Now, when building the library, how does the
> compiler know that it has to make virtual calls, even though no class
> in the library overrides the method, because some app code might
> derive from the class and override the method?
Foo foo = new Bar();
foo.blah(); // the compiler can be absolutely certain that foo refers to a Bar in this case
-- andy
|
April 21, 2004 Re: Virtual methods and class libraries | ||||
---|---|---|---|---|
| ||||
Posted in reply to Andy Friesen | On Tue, 20 Apr 2004 09:01:18 -0700, Andy Friesen wrote: > Foo foo = new Bar(); > foo.blah(); // the compiler can be absolutely certain that foo refers to > a Bar in this case No, it still sounds broken. class A { int somefunc() { return 1; } } extern A giveMeAnObject(); // link with a plugin that is supposed to subclass A A a = giveMeAnObject() a.somefun == 1; // true ------------- now in a shared library ----------------- class B : A { int somefunc() { return 2; } } A giveMeAnObject() { return new B(); } ------------------------------------------------------- The compiler when compiling the first binary will think nothing is subclassing A, so not make the methods virtual. Now the shared library cannot subclass A and return it using polymorphism. What am I missing here which makes this work? thanks -mike |
April 22, 2004 Re: Virtual methods and class libraries | ||||
---|---|---|---|---|
| ||||
Posted in reply to Mike Hearn | Mike Hearn wrote:
> On Tue, 20 Apr 2004 09:01:18 -0700, Andy Friesen wrote:
>
>>Foo foo = new Bar();
>>foo.blah(); // the compiler can be absolutely certain that foo refers to a Bar in this case
>
>
> No, it still sounds broken.
>
> class A {
> int somefunc() {
> return 1;
> }
> }
>
> extern A giveMeAnObject();
>
> // link with a plugin that is supposed to subclass A
> A a = giveMeAnObject()
> a.somefun == 1; // true
>
> ------------- now in a shared library -----------------
>
> class B : A {
> int somefunc() { return 2; }
> }
>
> A giveMeAnObject() { return new B(); }
>
> -------------------------------------------------------
>
> The compiler when compiling the first binary will think nothing is
> subclassing A, so not make the methods virtual. Now the shared library
> cannot subclass A and return it using polymorphism.
>
> What am I missing here which makes this work?
In this example, the compiler is only sure that giveMeAnObject yields an A instance. (which is enough to inline any final methods A may have, but little else) As you said, this isn't enough for the compiler to be able to optimize the virtual call out. Come to think of it, this would probably be enough for the compiler if A was declared as a final class.
In my example, the new operator was used directly, so the compiler had unambigious knowledge of the exact type of the object.
The trick is that the D compiler is optimizing specific method calls, not marking a given method as being inlineable or not.
-- andy
|
Copyright © 1999-2021 by the D Language Foundation