Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/146.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
异常处理时类型识别的工作原理 > C++代码中的某个地方: try { foo(); } catch (const FooExceptionOne& e) { // ... } catch (const FooExceptionTwo& e) { // ... } catch (const std::exception& e) { // ... }_C++_Exception_Exception Handling - Fatal编程技术网

异常处理时类型识别的工作原理 > C++代码中的某个地方: try { foo(); } catch (const FooExceptionOne& e) { // ... } catch (const FooExceptionTwo& e) { // ... } catch (const std::exception& e) { // ... }

异常处理时类型识别的工作原理 > C++代码中的某个地方: try { foo(); } catch (const FooExceptionOne& e) { // ... } catch (const FooExceptionTwo& e) { // ... } catch (const std::exception& e) { // ... },c++,exception,exception-handling,C++,Exception,Exception Handling,FooExceptionOne和FooExceptionTwo是从std::exception派生的自定义类 在抛出异常的时刻;类型识别是如何工作的?这是一种动态铸造或普利莫菲斯,发生在“引擎盖下” 我的第一个想法是动态的铸造,但是(当然)它看起来非常慢的解决方案。< /P> < P> GCC,Clang和英特尔C++编译器将这个类型推到登记册中,如在这个页面上可以看到的: 守则: switch (throwType) { case 0: throw 0; case 1:

FooExceptionOne
FooExceptionTwo
是从
std::exception
派生的自定义类

在抛出异常的时刻;类型识别是如何工作的?这是一种动态铸造或普利莫菲斯,发生在“引擎盖下”


我的第一个想法是动态的铸造,但是(当然)它看起来非常慢的解决方案。< /P> < P> GCC,Clang和英特尔C++编译器将这个类型推到登记册中,如在这个页面上可以看到的:

守则:

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
该类型的typeinfo在GCC中存储在
esi
寄存器中。但是,这是特定于编译器的,因此,尽管这是GCC(以及Clang和Intel)的情况,但可能不适用于任何其他编译器(Borland等)

< > >代码> >代码>的类型信息可以在编译时完全确定,因此不需要使用C++的RTI特性,因为它基本上是一个ID类型的枚举,用于映射到相应的catch块。
确定类型映射方式的规则可在标准第15.3节“异常处理”中找到

看看下面的文章和文章


编译器将生成包含异常typeinfo的数组/表,用于try/catch搜索。

不是答案,但异常应该由
const
引用捕获。我不确定它是如何工作的,但非常缓慢的解决方案在这里不是问题。例外情况不是为速度而设计的。