如何解决C ++如何实现运行时类型信息
我想知道C ++语言如何在运行时保存变量的类型信息。在我看来,运行时意味着将程序员编写的源代码文件编译为与特定机器相关的二进制格式的机器代码。该二进制文件全部由机器指令和操作数组成。在机器级别上,没有这样的东西。类型的概念只是存储在寄存器和存储器中的值。从机器的角度来看,这些值没有上层抽象类型。那么,如何在运行时(机器代码执行的过程)存储这些类型信息?我应该如何理解运行时类型信息的声明?
解决方法
有两种情况。
如果要检查的值具有多态类型,则编译器可以例如生成以某种方式将对象的vtable映射到静态类型信息块的代码。该块甚至可能在vtable中!
如果要检查的值具有已知的静态类型,则编译器可以直接直接插入指向该对象的类型信息的指针。
您所得到的答案会因编译器而异,但是我对使用GCC编译的简单程序进行了一些研究。 例如,给定以下定义:
template <class T>
const char* get_typeid(const T& val) {
return typeid(val).name();
}
class Static{};
class Dynamic {
public: virtual ~Dynamic() = default; // Making the class polymorphic
};
编译器可以为静态生成以下代码:
char const* get_typeid<Static>(Static const&):
push rbp
mov rbp,rsp
sub rsp,16
mov QWORD PTR [rbp-8],rdi
mov edi,OFFSET FLAT:typeinfo for Static
call std::type_info::name() const
leave
ret
请注意它如何访问全局常量(“ OFFSET FLAT:static的typeinfo”)。这意味着编译器已在编译时解决了typeid
调用。
与动态版本比较:
char const* get_typeid<Dynamic>(Dynamic const&):
push rbp
mov rbp,rdi
mov rax,QWORD PTR [rbp-8] # rax = pointer to Dynamic
mov rax,QWORD PTR [rax] # rax = vtable pointer of Dynamic
sub rax,8
mov rax,QWORD PTR [rax] #rax = typeinfo field of vtable
mov rdi,rax
call std::type_info::name() const
leave
ret
请注意,它如何通过获取传递的Dynamic对象的vtable并减去8来访问类型信息。为完整起见,以下是Dynamic vtable的定义:
vtable for Dynamic:
.quad 0
.quad typeinfo for Dynamic
.quad Dynamic::~Dynamic() [complete object destructor] # this is where the vtable normally points to.
.quad Dynamic::~Dynamic() [deleting destructor]
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。