Приложения, созданные с VS2017 в C ++ в режиме Release, не ломаются при необработанном исключении - PullRequest
0 голосов
/ 25 марта 2019

Этот вопрос относится к нативным программам на C ++, созданным VS2017, но выполненным ВНЕ VS IDE:

Почему необработанные исключения незаметно игнорируются в нативных сборках C ++ Release, тогда как сборки Debug ловят то же исключение и отображают приятноеожидаемое сообщение об ошибке?

Я попытался найти настройку сборки, которая влияет на необработанные исключения, но не удалось.

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

std::map<const string, const int> MyMap;

auto it = MyMap.find("Cant Find Me");
int res = it->second; //Dereferencing the end iterator causes the expected exception. This exception is not explicitly handled anywhere else.

В ответ на некоторые комментарии об утверждении «Отладка против исключения» я попытался выполнить его со следующим кодом, вызывающим исключение:

PCHAR p;
p = NULL;
*p = 'X';  //Provoke an exception by following a null pointer and awaiting the chaos and madness at its end...

Этот код по-прежнему не вызывает сообщений об ошибках при выполнении ВНЕ IDE MSVC.Теперь это происходит для ОБОИХ сборок Release и Debug.

1 Ответ

1 голос
/ 25 марта 2019

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

В отладочных сборках ваша конкретная реализация преобразует это в удобную для пользователя ошибку с понятным для человека сообщением.Это помощь при отладке.

В сборках релизов этого не происходит, поскольку сборки релизов не предназначены для отладки.Оставление кода отладки повредит общей производительности.

Приложение.Похоже, что ваш анализ ситуации с первым фрагментом кода выглядит следующим образом.

  1. Разыменование конечного итератора обычно вызывает исключение ЦП.
  2. Сборка выпуска активно отключает указанное исключение.
  3. В отладочной сборке исключение обрабатывается в соответствии с настройками ОС по умолчанию, что приводит к завершению с хорошим сообщением об ошибке.

Этот анализ неверен.Происходит следующее:

  1. Разыменование конечного итератора: неопределенное поведение .Реализация может делать то, что ей нравится.
  2. В сборке выпуска разыменование конечного итератора не приводит к исключению процессора или любой другой сразу же перехватываемой ошибке, что является нормальным для многих основных реализаций std::string вархитектура x86
  3. В отладочной сборке реализация активно вынуждает программу вызывать удобное для пользователя исключение при разыменовании конечного итератора за цену сниженной производительности.

Asдля второго фрагмента кода это может вызвать или не вызвать исключение ЦП, а исключение ЦП может вызвать или не вызвать дружественное пользователю сообщение об ошибке.Поведение это неопределено .Не совсем понятно, почему вы решили, что (1) исключение действительно происходит, и (2) оно незаметно игнорируется реализацией.Нет абсолютно никаких доказательств того, что это можно было бы предположить.Если происходит исключение ЦП, приложение, вероятно, просто ненормально завершает работу без какого-либо видимого пользователем сообщения об ошибке.Ваша IDE, включающая отладчик, способна отлавливать аварийное завершение и переводить его в удобную для пользователя ошибку даже для сборки выпуска.За пределами IDE вы сами по себе.

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