Вариант № 1: просто никогда не перехватывайте исключения.
Исключения не имеют много накладных расходов, когда они не выброшены или не пойманы; если вы бросаете и не готовы поймать, вы все равно умрете, так что влияние на производительность в этот момент тривиально. Также обратите внимание, что разматывание стека не будет выполняться, если исключение не обработано; программа просто прекратит работу без разматывания стека.
Важно отметить, что в G ++ у исключений почти нет накладных расходов, когда они на самом деле не генерируются. G ++ генерирует дополнительную информацию, достаточную для отслеживания выполнения программы через стек, и некоторый дополнительный код для вызова деструкторов и т. Д., Однако ни один из этого дополнительного кода или данных никогда не используется до тех пор, пока на самом деле не будет выдано исключение. Поэтому вы не должны видеть разницу в производительности между кодом с включенными исключениями, но не используемым, и кодом с отключенными исключениями (с помощью любого механизма).
Вариант № 2: Пропустить -fno-exceptions
.
Этот флаг указывает G ++ сделать две вещи :
- Все обработки исключений в библиотеках STL удалены; броски заменены на
abort()
, звонки
- Стек раскручивает данные и код удаляется. Это экономит некоторое пространство кода и может незначительно упростить распределение регистров для компилятора (но я сомневаюсь, что это сильно повлияет на производительность). Примечательно, однако, что если выдается исключение, и библиотека пытается размотаться с помощью кода
-fno-exceptions
, она прекратит работу в этот момент, поскольку данные для размотки отсутствуют.
Это, по сути, превратит все исключения в abort()
с, как вам бы хотелось. Однако обратите внимание, что вам не разрешат throw
- любые действительные значения throw
s или catch
s в вашем коде приведут к ошибке во время компиляции.
Вариант № 3: (не переносим и не рекомендуется!) Hook __cxa_allocate_exception.
Исключения C ++ реализованы с использованием (среди прочего) функций внутренней библиотеки __cxa_allocate_exception и __cxa_throw. Вы можете реализовать библиотеку LD_PRELOAD, которая подключает эти функции к abort ():
void __cxa_allocate_exception() { abort(); }
void __cxa_throw() { abort(); }
ВНИМАНИЕ: Это ужасный взлом. Он должен работать на x86 и x86-64, но я настоятельно рекомендую против этого. Примечательно, что на самом деле это не улучшит производительность и не сэкономит место на коде, как -fno-exceptions
. Однако он допускает синтаксис throw
, превращая throw
с в abort()
с.