2016-11-30 140 views
3

某处型recognision工作++代码:如何时异常在C处理

try 
{ 
    foo(); 
} 
catch (const FooExceptionOne& e) 
{ 
    // ... 
} 
catch (const FooExceptionTwo& e) 
{ 
    // ... 
} 
catch (const std::exception& e) 
{ 
    // ... 
} 

FooExceptionOneFooExceptionTwostd::exception派生自定义类。

在引发异常的时刻;类型识别如何工作?它是一种动态投射还是多面体,发生在“引擎盖下”?

我的第一个想法是动态铸造,但(当然)它似乎非常缓慢的解决方案。

+2

不是答案,但应该由'const'引用捕获异常。 –

+1

我实际上并不确定它是如何工作的,但是一个非常缓慢的解决方案在这里不会成为问题。例外情况不是为了速度而设计的。 –

回答

5

GCC,锵和Intel C++编译器推型到寄存器中,作为可以在此页中可以看出:https://godbolt.org/g/w0lD0p

的代码:

switch (throwType) { 
    case 0: 
    throw 0; 

    case 1: 
    throw 0.0; 

    case 2: 
    throw "test"; 
} 

被编译为以下汇编代码中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 

如从线可以看出:

mov  esi, OFFSET FLAT:typeinfo for int 
mov  esi, OFFSET FLAT:typeinfo for char const* 
mov  esi, OFFSET FLAT:typeinfo for double 

该类型的类型信息存储在esi寄存器中的GCC中。然而,这是编译器特有的,所以虽然GCC(以及Clang和Intel)的情况是这样,但它可能不适用于任何其他编译器(Borland等)。

throw使用的类型信息可以在编译时完全确定,因此它不需要使用C++的RTTI特性,因为它基本上是一个枚举类型的ids,用于映射到相应的catch块。

确定类型如何映射的规则可以在关于处理异常的标准的§15.3节中找到。