Reputation: 1
class B
{
public: virtual void fun1() {}
};
class D: public B
{
public: virtual void fun1() {}
};
int main()
{
//Empty Main.
//Not creating any object of B or D.
return 0;
}
In GCC or Visual Studio, will the compiler create any vTable here?
As per my understanding it should not create any vTables because we didn't create any B or C obj. So no need to create I think.
Am I correct?
Upvotes: 0
Views: 396
Reputation: 8268
Vtables are static data, pretty much like a constant array. There is one per (simple) polymorphic class. (Complex classes can have many vtables, but it's a detail.)
Like any other symbol, it can be referenced by code. If you create no instance of a class, it will not be needed, but it will be referenced by constructors of your class (but these constructors will be un-referenced symbols).
The linker might drop unneeded symbols.
Upvotes: 1
Reputation: 1354
Tried to see the assembly output of compiled C++ on https://godbolt.org/ with compiler as x86-64 gcc9.2
Case 1: link : https://godbolt.org/z/jFkC4Q
class B
{
public: virtual void fun1() {}
};
class D: public B
{
public: virtual void fun1() {}
};
int main()
{
//Empty Main.
//Not creating any object of B or D.
return 0;
}
The result for above code is :
main:
push rbp
mov rbp, rsp
mov eax, 0
pop rbp
ret
Case 2: link : https://godbolt.org/z/WyNY9j
class B
{
public: virtual void fun1() {}
};
class D: public B
{
public: virtual void fun1() {}
};
int main()
{
//Non Empty Main.
D d; // creating object of D
return 0;
}
The result for above code is :
D::fun1():
push rbp
mov rbp, rsp
mov QWORD PTR [rbp-8], rdi
nop
pop rbp
ret
main:
push rbp
mov rbp, rsp
mov eax, OFFSET FLAT:vtable for D+16
mov QWORD PTR [rbp-8], rax
mov eax, 0
pop rbp
ret
vtable for D:
.quad 0
.quad typeinfo for D
.quad D::fun1()
typeinfo for D:
.quad vtable for __cxxabiv1::__si_class_type_info+16
.quad typeinfo name for D
.quad typeinfo for B
typeinfo name for D:
.string "1D"
typeinfo for B:
.quad vtable for __cxxabiv1::__class_type_info+16
.quad typeinfo name for B
typeinfo name for B:
.string "1B"
In the second case we can see that the vtable is created.
Upvotes: 1
Reputation: 16873
When using gcc, a vtable is emitted (created) in the translation unit that defines the first non-inline virtual, but not pure virtual, method of the class. This does not depend on whether or not any objects of that class are created. (In your example, there are no such functions. However, that does not seem to be the point of your question so I'll ignore that.)
The linker is free to discard anything it can prove is not used, though. So it is possible that the vtable might not be present in your final executable, even though the compiler created it.
Upvotes: 2