编译器是否会创建vtable,而不考虑在c++中创建对象
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;
}
在GCC或Visual Studio中,编译器会在此处创建任何vTable吗?
根据我的理解,它不应该创建任何vTables,因为我们没有创建任何B或C对象。所以我认为没有必要创建。
我说得对吗?
使用gcc时,在定义类的第一个非内联虚拟(但不是纯虚拟(方法的转换单元中发出(创建(vtable。这并不取决于是否创建了该类的任何对象。(在你的例子中,没有这样的函数。然而,这似乎不是你问题的重点,所以我将忽略它。(
不过,链接器可以自由丢弃任何可以证明未使用的内容。因此,vtable可能不会出现在您的最终可执行文件中,即使编译器创建了它
尝试查看编译后的C的汇编输出++在…上https://godbolt.org/编译器为x86-64 gcc9.2
案例1:链接: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;
}
上述代码的结果是:
main:
push rbp
mov rbp, rsp
mov eax, 0
pop rbp
ret
案例2:链接: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;
}
上述代码的结果是:
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"
在第二种情况下,我们可以看到vtable已经创建。
Vtables是静态数据,非常像常量数组。每个(简单(多态类有一个。(复杂类可以有许多vtable,但这是一个细节。(
与任何其他符号一样,它可以被代码引用。如果不创建类的实例,则不需要它,但它将被类的构造函数引用(但这些构造函数将是未引用的符号(。
链接器可能会删除不需要的符号。
相关文章:
- 不考虑模板构造函数
- 为什么子项目 CMAKE 不考虑 fno-sanitize,请禁用目标的消毒器
- 如何对向量进行排序<浮点数,字符串>而不考虑字符串
- 编译器是否会创建vtable,而不考虑在c++中创建对象
- CFileFind不考虑目录的第一个文件
- 初始化值是否保证通过其自己的地址反映,而不考虑内存顺序
- 矢量重新分配,而不考虑储备
- GlobalMemoryStatusEx 不考虑新阵列
- 如何创建一个程序来标识最长的子字符串回文,而不考虑字母大小写
- OpenGL不考虑GL_DIFFUSE位置光的距离
- Eclipse 问题 - 编译期间不考虑 .c 和 .cpp 文件中定义的预处理
- std::unordered_set 是否对任何对象进行摊销常量查找时间,而不考虑谓词
- 如何对对象数组进行排序,而不考虑对象变量类型
- C++11:编译器何时将 {} 视为 std::initializer_list,何时不考虑?
- 为什么用于输入验证的 while 循环要么完全跳过循环,要么不考虑错误的输入
- 为什么在这种情况下不考虑依赖于参数的查找?
- 为什么不考虑特定值的模板
- std::atomic 是否提供原子行为,而不考虑排序?
- Visual studio:在生成过程中复制内容,而不考虑 cpp 更改
- 强制 NVCC 不考虑常量内存的构造函数