Подтвердить что ты не робот

Отключение исключений С++, как я могу сделать любой std:: throw() немедленно прекратить?

Эта программа на С++ является CGI script, у меня нет желания справляться с исключениями. Я бы предпочел получить предельное повышение производительности и позволить ОС (Linux) обрабатывать очистку после того, как процесс замирает.

Я использую стандартную библиотеку С++ и хочу, чтобы какая-либо функция была die как в Perl: Всякий раз, когда она генерирует исключение. Без размотки или запуска любого дополнительного кода в моем процессе.

Как работает -fno-exceptions? Если у меня вообще нет уловов в моем коде и в основном делаю вид, что исключений не существует. но я do использую библиотеку std:: С++, которая может throw()?

4b9b3361

Ответ 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.

Ответ 2

-fno-exceptions превращает всю стандартную библиотеку в вызов std::abort(). Это обрабатывает часть, которую вы не можете изменить напрямую, остальное - не использовать их вообще в вашем коде.

Конечно, я действительно сомневаюсь в вашем оправдании в этом. Вы только "теряете" производительность, когда на самом деле бросаете, и вы выбрасываете значительный и полезный бит языка.

Ответ 3

Цитата:

Эта программа на С++ является CGI script, я не хочу иметь дело с исключениями.

  • Тогда нет. Просто. Исключение будет очень быстро попадать в верхнюю часть стека.

Но я бы призвал вас сделать это. Это означает, что вы думаете о том, что может пойти не так.

Ответ 4

Если кто-то наткнется на этот вопрос, я хотел бы исправить то, что @GManNickG и (fooobar.com/questions/257677/...) и @bdonlan (fooobar.com/questions/257677/...) в ответах. К сожалению, часть "исключение -fno-exception", удаляющая весь код обработки исключений и превращая все броски в прерывания, неверна. Хорошо - частично неправильно. Это верно при компиляции данной библиотеки (libstdС++ v3) с этим флагом, но не так, если вы используете эту библиотеку (как .a или .so или .dll или что-то еще) в своем собственном коде, скомпилированном с этим флагом, В последнем случае код обработки исключений в ВАШЕМ коде запрещен, но все вызовы обработки исключений внутри библиотеки остаются (поскольку библиотека была скомпилирована БЕЗ этого флага с включенными исключениями), поэтому, если вы используете new, то ваш исполняемый файл У WILL есть код обработки исключений - единственное отличие состоит в том, что вы не можете ничего об этих исключениях с catch() (что запрещено в вашем коде), поэтому все они эффективно заканчиваются как abort(), но только потому, что их никто не ловит.

Ответ 5

Просто не ловите их в своем коде. В этом случае вызывается обработчик завершения, и ваша программа будет "сбой".