在发布模式下使用VS2017 C ++构建的应用不会在未处理的异常时中断

时间:2019-03-25 02:32:28

标签: c++ exception x86 visual-studio-2017

此问题是指由VS2017构建但在VS IDE外部执行的本机C ++程序:

为什么未处理的异常在本机C ++ Release版本中被静默忽略,而Debug版本捕获相同的异常并显示出很好的预期错误消息?

我试图找到影响未处理的Exeptions的构建设置,但失败了。

下面列出了生成异常的代码。
请注意,我并不是在问如何修复此代码并避免异常(或如何处理),而是如何取消忽略。 strong>此版本中的异常会生成,因此操作系统会捕获并抱怨。

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...

在MSVC IDE的外部执行时,此代码仍然不会引发任何错误消息。现在,发布和调试版本都会发生这种情况。

1 个答案:

答案 0 :(得分:1)

取消引用最终迭代器是未定义的行为。允许实现做自己喜欢的事情。

在调试版本中,您的特定实现将其转换为带有人类可读消息的友好的用户友好错误。这是调试辅助。

在发行版本中,它不是,因为发行版本不用于调试。保留调试代码会损害整体性能。

附录。看起来您对第一个代码片段的情况的分析如下。

  1. 取消引用最终迭代器通常会导致CPU异常。
  2. 发布版本积极地消除了所述异常。
  3. 调试版本将按照操作系统默认值处理异常,这会导致终止并显示一条错误消息。

此分析不正确。发生的情况如下:

  1. 取消引用最终迭代器是未定义的行为。允许实现做自己喜欢的事情。
  2. 在发行版中,取消引用最终迭代器不会导致CPU异常或任何其他可立即捕获的错误,这在x86架构上std::string的许多主流实现中都是很常见的
  3. 在调试版本中,实现会主动使程序在取消引用最终迭代器时引发用户友好的异常,从而降低性能。

对于第二个代码片段,它可能会或可能不会导致CPU异常,并且CPU异常可能会或可能不会导致用户友好的错误消息。它的行为是 undefined 。尚不清楚为什么您决定(1)确实发生异常,并且(2)某个实现将其默默忽略。绝对没有证据表明这一点。如果确实发生CPU异常,则应用程序可能会异常终止,而不会出现任何用户可见的错误消息。您的IDE(包括调试器)能够捕获异常终止并将其转换为用户友好的错误,即使是对于发行版也是如此。在IDE之外,您是一个人。