Реализации могут отличаться, но есть некоторые основные идеи, которые вытекают из требований.
Сам объект исключения - это объект, созданный в одной функции и уничтоженный в вызывающей стороне. Следовательно, обычно невозможно создать объект в стеке. С другой стороны, многие объекты исключений не очень большие. Например, можно создать, например, 32-байтовый буфер и переполнить до кучи, если на самом деле нужен объект большего размера.
Что касается фактической передачи контроля, существуют две стратегии. Одним из них является запись достаточного количества информации в самом стеке, чтобы разматывать стек. В основном это список деструкторов для запуска и обработчиков исключений, которые могут перехватить исключение. Когда возникает исключение, запускайте стек, выполняя эти деструкторы, пока не найдете соответствующий улов.
Вторая стратегия перемещает эту информацию в таблицы вне стека. Теперь, когда возникает исключение, стек вызовов используется, чтобы выяснить, какие области вводятся, но не выходятся. Затем они просматриваются в статических таблицах, чтобы определить, где будет обработано выброшенное исключение, и какие деструкторы выполняются между ними. Это означает, что в стеке меньше издержек на исключение; обратные адреса нужны в любом случае. Таблицы являются дополнительными данными, но компилятор может поместить их в загруженный по требованию сегмент программы.