Dan*_*nyX 3 c++ exception-handling exception
在c ++代码中的某处:
try
{
foo();
}
catch (const FooExceptionOne& e)
{
// ...
}
catch (const FooExceptionTwo& e)
{
// ...
}
catch (const std::exception& e)
{
// ...
}
Run Code Online (Sandbox Code Playgroud)
FooExceptionOne并且FooExceptionTwo是从中派生的自定义类std::exception.
在抛出异常的那一刻; 类型识别如何工作?它是某种动态铸造还是plymorphism,发生在"引擎盖下"?
我的第一个想法是动态铸造,但(当然)它似乎是非常缓慢的解决方案.
GCC,Clang和英特尔C++编译器将类型推送到寄存器,如本页所示:https://godbolt.org/g/w0lD0p
代码:
switch (throwType) {
case 0:
throw 0;
case 1:
throw 0.0;
case 2:
throw "test";
}
Run Code Online (Sandbox Code Playgroud)
在GCC中编译为以下汇编代码:
.L17:
mov edi, 4
call __cxa_allocate_exception
xor edx, edx
mov DWORD PTR [rax], 0
mov esi, OFFSET FLAT:typeinfo for int
mov rdi, rax
call __cxa_throw
.L4:
mov edi, 8
call __cxa_allocate_exception
xor edx, edx
mov QWORD PTR [rax], OFFSET FLAT:.LC1
mov esi, OFFSET FLAT:typeinfo for char const*
mov rdi, rax
call __cxa_throw
.L3:
mov edi, 8
call __cxa_allocate_exception
xor edx, edx
mov QWORD PTR [rax], 0x000000000
mov esi, OFFSET FLAT:typeinfo for double
mov rdi, rax
call __cxa_throw
Run Code Online (Sandbox Code Playgroud)
从行中可以看出:
mov esi, OFFSET FLAT:typeinfo for int
mov esi, OFFSET FLAT:typeinfo for char const*
mov esi, OFFSET FLAT:typeinfo for double
Run Code Online (Sandbox Code Playgroud)
该类型的typeinfo存储在esi寄存器中的GCC中.然而,这是特定于编译器的,因此虽然GCC(以及Clang和Intel)也是如此,但它可能不适用于任何其他编译器(Borland等).
使用的类型信息throw可以在编译时完全确定,因此不需要使用C++的RTTI特性,因为它基本上是类型ids的枚举,用于映射到相应的catch块.
确定类型映射方式的规则可以在标准的第15.3节中找到,关于处理异常.
| 归档时间: |
|
| 查看次数: |
93 次 |
| 最近记录: |