簡體   English   中英

在發布模式下使用VS2017 C ++構建的應用不會在未處理的異常時中斷

[英]Apps built with VS2017 in C++ in Release mode do not break on unhandled exception

這個問題是指由VS2017構建但在VS IDE的外部執行的本機C ++程序:

為什么未處理的異常在本機C ++ Release版本中被靜默忽略,而Debug版本捕獲相同的異常並顯示期望的錯誤消息?

我嘗試找到影響未處理的Exeptions的構建設置,但失敗了。

下面列出了生成異常的代碼。
請注意,我並不是在問如何修復此代碼並避免異常(或如何處理),而是在Release版本中如何忽略此異常,因此操作系統會捕獲並抱怨。

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.

為了回應有關Debug Assertion vs. Exception的一些評論,我嘗試使用以下引發異常的代碼進行嘗試:

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. 取消引用結束迭代器通常會導致CPU異常。
  2. 發布版本積極地消除了上述異常。
  3. 調試版本將按照操作系統默認值處理異常,這會導致終止並顯示一條錯誤消息。

該分析是不正確的。 發生的情況如下:

  1. 取消引用最終迭代器是未定義的行為 一個實現被允許做自己喜歡的事情。
  2. 在發行版本中,取消引用最終迭代器不會導致CPU異常或任何其他可立即捕獲的錯誤,這在x86體系結構上的許多主流std::string實現中都是正常的
  3. 在調試版本中,實現會主動使程序在取消引用最終迭代器時引發用戶友好的異常,從而降低性能。

至於第二個代碼片段,它可能會或可能不會導致CPU異常,並且CPU異常可能會或可能不會導致用戶友好的錯誤消息。 它的行為是不確定的 尚不清楚為什么您決定(1)確實發生異常,並且(2)某個實現將其默默忽略。 絕對沒有證據表明這一點。 如果確實發生CPU異常,則應用程序可能會異常終止,而不會出現任何用戶可見的錯誤消息。 您的IDE(包括調試器)能夠捕獲異常終止並將其轉換為用戶友好的錯誤,即使是對於發行版也是如此。 在IDE之外,您是一個人。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM