http://gcc.gnu.org/bugzilla/show_bug.cgi?id=50243
Bug #: 50243 Summary: vtable for pure abstract class (interface) shouldn't be emitted Classification: Unclassified Product: gcc Version: 4.5.2 Status: UNCONFIRMED Severity: enhancement Priority: P3 Component: c++ AssignedTo: unassig...@gcc.gnu.org ReportedBy: congru...@yahoo.co.uk Note: this is probably easier to do if ‘Bug 34949 - Dead code in empty destructors.’ is done. Consider the following class: class iface { protected: ~iface() { } public: virtual void a() = 0; virtual void b() = 0; virtual void c() = 0; }; This class cannot be instantiated, so a, b and c cannot be called from outside. The only possible call site for them would be the destructor ~iface() but from the fact that a, b and c are pure and the fact that it compiles, we know that this doesn't happen. So the vtable for this class shouldn't be emitted. But it is: __ZTV5iface: .long 0 .long 0 .long ___cxa_pure_virtual .long ___cxa_pure_virtual .long ___cxa_pure_virtual To make matters worse, it's needlessly referenced in destructors of derived classes: __ZN4impl1cEv: pushl %ebx subl $8, %esp movl 16(%esp), %ebx testl %ebx, %ebx je L3 movl $__ZTV4impl+8, (%ebx) <--- Strictly speaking unnecessary call __Z7dostuffv movl $__ZTV5iface+8, (%ebx) <--- OOPS movl %ebx, 16(%esp) What follows is the inlined addl $8, %esp destructor of iface, the popl %ebx iface vtable isn't needed. jmp __ZdlPv For this example I deliberately used a small interface, but I have found that in larger software projects the unnecessary vtables can add up. For reference, the rest of code used to demonstrate the problem follows: void dostuff(); class impl : public iface { private: ~impl() { dostuff(); } public: void a() { dostuff(); } void b() { dostuff(); } void c() { delete this; } }; void test() { iface * y = new impl(); y->a(); y->b(); y->c(); }