This is the mail archive of the
gcc-bugs@gcc.gnu.org
mailing list for the GCC project.
[Bug c++/50243] New: vtable for pure abstract class (interface) shouldn't be emitted
- From: "congruwer at yahoo dot co.uk" <gcc-bugzilla at gcc dot gnu dot org>
- To: gcc-bugs at gcc dot gnu dot org
- Date: Tue, 30 Aug 2011 20:50:32 +0000
- Subject: [Bug c++/50243] New: vtable for pure abstract class (interface) shouldn't be emitted
- Auto-submitted: auto-generated
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: unassigned@gcc.gnu.org
ReportedBy: congruwer@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();
}