rahi
rahi

Reputation: 1

Will compiler create vtable irrespective of object creation in c++

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

Answers (3)

curiousguy
curiousguy

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

Abhishek Chandel
Abhishek Chandel

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

JaMiT
JaMiT

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

Related Questions