Question: When an exception is thrown in `C++` and the stack is unwound, how is is the correct handler (`catch` clause) picked to handle the exception?

```
void f1()
{
    throw 1;
}

void f2()
{
    try
    {
        f1();
    }
    catch(const char* e)
    {
        std::cout << "exc1";
    }
}

...
try
{
    f2();
}
catch(int& e)
{
    std::cout << "exc2";
}
...

```

For example this code unsurprisingly prints `"exc2"` because `catch(int& e)` is capable of handling the `1` `int` typed object.

What I don't understand is, how can this be resolved statically? Or is it resolved dynamically? Is type information propagated with the exception?

Answer: 
You could say that "the type information is propagated with the exception", but technically that's not true. When you `throw` something, that object gets copied/moved and the compiler will look for a [appropriate `catch` clause](http://en.cppreference.com/w/cpp/language/try_catch) in the order that they appear, where the object will get copied/moved to:

> 
> The exception is a match if any of the following is true:
> 
> 
> * E and T are the same type (ignoring top-level cv-qualifiers on T)
> * T is an lvalue-reference to (possibly cv-qualified) E
> * T is an unambiguous public base class of E
> * T is a reference to an unambiguous public base class of E
> * T is (possibly cv-qualified) U or const U& (since C++14), and U is a pointer or pointer to member (since C++17) type, and E is also a pointer or pointer to member (since C++17) type that is implicitly convertible to U by one or more of
> 
> 
> 	+ a standard pointer conversion other than one to a private, protected, or ambiguous base class
> 	+ a qualification conversion
> 	+ a function pointer conversion
> 	 (since C++17)
> 	+ T is a pointer or a pointer to member or a reference to a const pointer (since C++14), while E is `std::nullptr_t`.
> 
> 
> 

Additionally, if there is a catch-all clause (`catch (...)`), then it is taken if any of the above points do not apply. If no `catch` clause is suitable, the exception continues its way up the call stack.
As some answers and comments have stated, the compiler does generate runtime type information RTTI for exception types that the exception dispatcher uses to match the right handler to an exception object.

As you can see from a modified version of my example here:

<https://godbolt.org/g/dyheBZ>

The compiler (gcc) generates a `typeinfo` block in section `.rodata` for objects that are used in `throw` or `catch` statements:

```
    .size   typeinfo for A, 16
typeinfo for A:
    .quad   vtable for __cxxabiv1::__class_type_info+16
    .quad   typeinfo name for A
    .weak   typeinfo name for A
    .section        .rodata._ZTS1A,"aG",@progbits,typeinfo name for A,comdat
    .type   typeinfo name for A, @object
    .size   typeinfo name for A, 3
typeinfo name for A:
    .string "1A"
    .text
    .type   __static_initialization_and_destruction_0(int, int), @function

```

And the `throw A();` statement uses this information to throw the exception:

```
    mov     edi, 1
    call    __cxa_allocate_exception
    mov     edx, 0
    mov     esi, OFFSET FLAT:typeinfo for A
    mov     rdi, rax
    call    __cxa_throw

```