А можно и вообще без исключений обойтись.
Обработчики исключений работают хорошо только в однородной среде. Но стоит скрестить библиотеку на одном языке и прогу на другом языке - как сразу начинается моя-твоя-непонимать...
У меня была простая идея реализации (для x86) обработки исключений - внутри блока - компилятор знает где происходит исключение (оператор raise). Так же исключения могут передаться из вызываемых функций. Тут делаем так: если функция отрабатывает без исключения, то при возврате сбрасывает флаг cf в ноль и возвращает результат как обычно, если функция не обрабатывает исключение, то она устанавливает флаг cf в единицу, а в регистр eax записывает код исключения (или указатель на объект исключений) и возвращает управление. В вызывающем коде после вызова ставиться условный переход на обработчик исключения jc _handler.
_handler для блока try/finally
- Код: Выделить всё
- _handler:
 push eax ; сохраняем объект-исключение (или можно использовать переменную)
 <код блока finally>
 pop eax ; восстанавливаем объект-исключение
 stc ; устанавливаем флаг cf в 1
 ret
_handler для блока try/except
- Код: Выделить всё
- _handler:
 <код блока except>
 jmp _continue ; возвращаемся к коду после блока try/except
 
Если в функции нет блока try/finally/except, то вставляется простой код
- Код: Выделить всё
- _handler: ret
Т.е. уже установленный флаг cf и регистр eax передаются далее вверх по цепочке вызова.
Оператор raise Exception.Create:
- Код: Выделить всё
- call Excpetion.Create ; в eax указатель на объект-исключение
 stc ; устанавливаем флаг cf
 jmp _handler ; переходим к обработчику
 
Кто-то заметит в этой схеме недостаток - не обрабатываются аппаратные исключения (например деление на ноль, и чтение недопустимого адреса и т.п.). А может их лучше не допускать? Ведь аппаратное исключение есть следствие кривых рук программиста... Зато будет работать в любой ОСи, т.к. не опирается ни на какие функции ОСи...
А для согласования кода на разных языках, нужно добавить как минимум директиву no_exception, типа как в C++ у функции можно дописать throw(), что означает, что данный код не передает никаких исключений. И если вы попытаетесь передать исключение, то компилятор поругает вас ошибкой компиляции... И требовать чтобы все экспортируемые функции использовали этот флаг или определяли его автоматически...