Что именно произойдет, если я отключу исключения C ++ в проекте? - PullRequest
18 голосов
/ 03 июня 2009

Visual C ++ имеет параметр компилятора «Включить исключения C ++», который можно установить на «Нет». Что именно произойдет, если я настрою это так? Мой код никогда явно не генерирует и не перехватывает исключения (и, следовательно, первое выброшенное исключение в любом случае прекратит работу программы) и не полагается на разматывание стека. Стоит ли ожидать повторного компилирования программы от нежелательного поведения?

Ответы [ 7 ]

15 голосов
/ 03 июня 2009

Документация MSDN настройки объясняет различные режимы исключений и даже дает примеры кода, чтобы показать разницу между различными режимами. Кроме того, эта статья может быть интересной, даже если она довольно старая.

Итог: опция в основном включает или отключает отслеживание продолжительности жизни всех ваших объектов. Такое отслеживание требуется, потому что в случае исключения должны быть вызваны все надлежащие деструкторы, должен быть разбит стек, а также проведена большая очистка. Такое отслеживание требует организационных накладных расходов (= дополнительный код) - это можно отбросить, установив параметр «Нет».

Я не пробовал сам, но похоже, что вы все еще можете throw и catch исключения, если для параметра установлено значение "Нет", но очистка и размотка отсутствуют, что может привести к последствия (не рекомендуется;) ..

4 голосов
/ 03 июня 2009

Компилятор пропустит деструкторы и другой код разматывания стека, который очищается после объектов C ++, когда они выходят из области видимости в результате исключения.

Другими словами, он пропускает кучу кода очистки. Это значительно улучшит производительность , но также вызовет серьезное зло, если исключение действительно будет брошено. (Прикинь время сам, если не веришь мне.)

Разница в производительности на самом деле не является причиной отключения исключений, за исключением некоторых критически важных приложений, где вы будете абсолютно обязаны это делать.

2 голосов
/ 03 июня 2009

Код, с которым я работал, всегда отключает исключения. Я не видел проблем с повреждениями или перебором ресурсов.

Я думал, что исключения, как правило, плохо подходят для c ++. Струйная обработка, особенно при отсутствии GC, делает все исключения исключенными. А затем дебаты о том, что на самом деле означает «исключительное», по сравнению с возможными неудачами.

2 голосов
/ 03 июня 2009

Вы по-прежнему будете иметь доступ к Структурной обработке исключений (SEH), которая может обрабатываться __try, __except и __finally.

Обработка исключений в C ++ - это просто реализация класса, построенная поверх SEH.

Компилятор также будет жаловаться, если вы попытаетесь создать экземпляры классов в функции, имеющей обработчик исключений SEH (жалуется на объекты, требующие разворачивания, т.е. классы), что может быть немного беспорядочным, но есть способы обойти это.

2 голосов
/ 03 июня 2009

Когда вы говорите «НЕТ» «Включить исключения C ++», синхронная модель обработки исключений компилятором (/ GX или / EHsc) не выбирается. В этом режиме семантика раскрутки не будет включена. То есть объект с автоматическим сохранением в кадре между функцией, выполняющей бросок, и функцией, выполняющей бросок, не будет уничтожен.

Вы можете обратиться к MSDN или Часто задаваемые вопросы по исключениям Visual C ++ для получения дополнительной информации об обработке исключений.

class Test
{
public:

    Test()
    {
        printf("Test::constructor");
    }
    ~Test()
    {
        printf("Test::Destructor");
    }

};


int _tmain(int argc, _TCHAR* argv[])
{
    int a;

 try
   {
     Test a;
     int* p = 0;
     *p = 0; // Cause access violation
   }
   catch (...)
   {
      printf("Caught access violation"); 
   }
    return 0;
}

с исключением исключения для обработки вывода будет:

Test::constructor
Caught access violation
1 голос
/ 03 июня 2009

Что касается Standard C ++, вы получите неопределенное поведение. Стандарт C ++ не допускает возможности глобального исключения исключений, а определенные операции стандартной библиотеки определяются как выбрасывание исключений при определенных обстоятельствах.

0 голосов
/ 03 июня 2009

Если operator new не удается выделить память, я полагаю, что он вернет NULL вместо того, чтобы выдавать исключение std::bad_alloc.

Если вы сделаете какие-либо обращения к сторонним библиотекам, которые генерируют исключения, это приведет к серьезным последствиям.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...