Final can be implemented in C++!

Started by
71 comments, last by Shannon Barber 21 years, 10 months ago
quote:Original post by Arild Fines
If you call a virtual method from a derived class pointer in C++, there will be a virtual lookup. If the compiler had been able to recognize the derived as a final class(or that this particular method was declared final)

If you add inline to the method declaration, and make the call using an explicit class declaration, the virtual call can be removed as follows:

ex.

  struct Base#include <iostream>using namespace std;struct Base	{	inline virtual Test()=0		{		cout<<"Base"<<endl;		}	};struct Sub : Base	{	Sub()		{		//Always call Base::Test, never anything else.		//Similar effect to final, except you decide		// at the invocation point, not at the class declaration		//More flexibility, but more work too		this->Base::Test();		}	inline virtual Test()		{		cout<<"Sub"<<endl;		}	};int main(){	Sub sub;	return 0;}  


Assembly output showing optimization, which has completely removed all method calls (virtual or otherwise), the cout is invoked directly inside of main.

  ; Listing generated by Microsoft (R) Optimizing Compiler Version 13.00.9466 	TITLE	Crap4.cpp	.386Pinclude listing.incif @Version gt 510.model FLAT;***SNIP***PUBLIC	_main; Function compile flags: /Ogty;	COMDAT _main_TEXT	SEGMENT_main	PROC NEAR					; COMDAT; 33   : {	push	esi; 34   : 	Sub sub;	push	OFFSET FLAT:??_C@_04NGEJNKEG@Base?$AA@	push	OFFSET FLAT:?cout@std@@3V?$basic_ostream@DU?$char_traits@D@std@@@1@A ; std::cout	call	??6std@@YAAAV?$basic_ostream@DU?$char_traits@D@std@@@0@AAV10@PBD@Z ; std::operator<<	add	esp, 8	mov	esi, eax	push	10					; 0000000aH	mov	ecx, esi	call	?put@?$basic_ostream@DU?$char_traits@D@std@@@std@@QAEAAV12@D@Z ; std::basic_ostream<char,std::char_traits<char> >::put	mov	ecx, esi	call	?flush@?$basic_ostream@DU?$char_traits@D@std@@@std@@QAEAAV12@XZ ; std::basic_ostream<char,std::char_traits<char> >::flush; 35   : 	return 0;	xor	eax, eax	pop	esi; 36   : }	ret	0_main	ENDP  


I reassert that final does not enable any optimizations, it merely removes bloat.
- The trade-off between price and quality does not exist in Japan. Rather, the idea that high quality brings on cost reduction is widely accepted.-- Tajima & Matsubara
Advertisement
quote:Original post by Arild Fines
If you call a virtual method from a derived class pointer in C++, there will be a virtual lookup. If the compiler had been able to recognize the derived as a final class(or that this particular method was declared final), the virtual lookup could be optimized out.


I don''t really see your argument. What kind of optimizations are you referring to?

If a class has virtual functions, and you are calling using a pointer to the base class, there is a vtable generated. Even if you have declared the method as final, you would still need the virtual lookup.

If you explictly call to the subclass virtual method, it''s already could avoid the virtual lookup. If you are not using through the base interace, the lookup can also be avoided.

Both of these depends on implementation of course.

An example

  class Base{public:  virtual void Method();};class Derived : public Base{public:  void Method();  void Call()  {    Derived::Method();  // explicit call, no vtable lookup  }};int main(){  Derived derived;  derived.Method();  // no vtable lookup  Base *base;  base->Method();  // lookup needed whether final or not  return 0;}  


Why measure from 98? Because before that, C++ was considered experimental and was officially standardized in 98.
quote:Original post by Void
If a class has virtual functions, and you are calling using a pointer to the base class, there is a vtable generated. Even if you have declared the method as final, you would still need the virtual lookup.

Ah, but you don''t. If the class is declared final, you *know* there''s no derived classes. Therefore they /must/ be calling the method of the finalized class. Ergo, the virtual look-ups can be avoided for that class; and that is what optimizing Java compilers do. It''s a significant capibility in Java, because all methods are the equivalent of C++ virtual by default.

quote:
If you explictly call to the subclass virtual method, it''s already could avoid the virtual lookup. If you are not using through the base interace, the lookup can also be avoided.

This is what he didn''t realize
I imagine you could do the same thing in Java (though it really wouldn''t surprize me if they ''removed'' that complexity, only to add it back in, in the form of final
- The trade-off between price and quality does not exist in Japan. Rather, the idea that high quality brings on cost reduction is widely accepted.-- Tajima & Matsubara

This topic is closed to new replies.

Advertisement