D - Virtual methods and class libraries
- Mike Hearn (17/17) Apr 19 2004 Hi,
- Walter (4/14) Apr 19 2004 You're right. For those cases, a virtual call will be made. And, even if...
- Alexander Larsson (7/26) Apr 20 2004 I still don't get it. The typical use case here would be writing a share...
- Andy Friesen (5/11) Apr 20 2004 Foo foo = new Bar();
- Mike Hearn (22/25) Apr 21 2004 No, it still sounds broken.
- Andy Friesen (11/47) Apr 21 2004 In this example, the compiler is only sure that giveMeAnObject yields an...
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
Apr 19 2004
"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[].
Apr 19 2004
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...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?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[].
Apr 20 2004
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
Apr 20 2004
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 caseNo, 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
Apr 21 2004
Mike Hearn wrote:On Tue, 20 Apr 2004 09:01:18 -0700, Andy Friesen wrote: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. -- andyFoo foo = new Bar(); foo.blah(); // the compiler can be absolutely certain that foo refers to a Bar in this caseNo, 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?
Apr 21 2004