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