Reputation: 405
Somewhere in c++ code:
try
{
foo();
}
catch (const FooExceptionOne& e)
{
// ...
}
catch (const FooExceptionTwo& e)
{
// ...
}
catch (const std::exception& e)
{
// ...
}
FooExceptionOne
and FooExceptionTwo
are custom classes derived from std::exception
.
In moment when exception is thrown; how does type recognition works? Is it some kind of dynamic casting or plymorphism, happening "under the hood"?
My first thought was dynamic-casting, but (of course) it seems very slow solution.
Upvotes: 3
Views: 212
Reputation: 5110
Take a look on following articles C++ exception handling internals and Exception Handling in LLVM.
Compiler will generate array/table with exceptions typeinfo for try/catch to search.
Upvotes: 0
Reputation: 7220
GCC, Clang and the Intel C++ compiler pushes the type into a register, as can be seen on this page: https://godbolt.org/g/w0lD0p
The code:
switch (throwType) {
case 0:
throw 0;
case 1:
throw 0.0;
case 2:
throw "test";
}
Is compiled to the following assembly code in 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
As it can be seen from the lines:
mov esi, OFFSET FLAT:typeinfo for int
mov esi, OFFSET FLAT:typeinfo for char const*
mov esi, OFFSET FLAT:typeinfo for double
The typeinfo for the type is in GCC stored in the esi
register. However this is compiler specific, so while this is the case for GCC (as well as Clang and Intel) it might not be for any other compiler (Borland, etc.).
The type info used by throw
can be completely determined at compile time, so this does not need to use the RTTI feature of C++, as it is basically an enumeration of type ids, that are used to map to the corresponding catch block.
The rules determining how types are mapped, can be found in the standard, section § 15.3, about handling exceptions.
Upvotes: 5