2011-06-29 73 views
6

我有Enable C++ Exceptions內置的第三方靜態庫設置爲沒有/EH標誌未指定)。從啓用C++異常的代碼中調用它(/EHa)有什麼後果?如果從庫中拋出結構化異常,主應用程序提供給_set_se_translator的函數是否會被可靠地調用? (我的實驗表明它會,但只是想知道這是否是定義的行爲)。在Visual Studio 2010中混合異常處理模型的後果是什麼?

混合/EH異常處理模型時是否還有其他注意事項?

+0

從技術上講,標準會說會導致破壞ODR的未定義行爲。我假設你想要更具體的解釋,但是(這就是爲什麼這是一個評論)。 –

+3

@Billy ONeal:當你禁用異常時,你立即擊中了UB;混合不會使情況變得更糟。 UB沒有進入度數。 – MSalters

+0

@ MSalters:哈哈 - 甚至沒有想到這一點。確實如此。 –

回答

5

調用爲沒有啓用異常的代碼不應該產生任何問題 - 這與調用外部C函數或此類性質沒有什麼不同。

調用代碼沒有啓用(爲例外啓用的碼)的異常可能不會包含正確的堆棧在異常殘疾人代碼展開語義,這意味着你將打破這一代碼不變,除非它專門設計用於處理例外情況。 (例如,某些庫(例如ANTLR)分配塊中的所有內存並讓用戶代碼一次釋放所有內容,即使它們本身不使用異常,也可以使用異常而不會泄漏)。

Raymond Chen有一篇關於C++的異常處理如何在MSVC++上工作的內部文章。長話短說,它建立在Windows'SEH之上。因此,它的行爲應該類似於在例如拋出SEH異常時發生的情況。 C代碼。 (不過,我不是這個驗證自己)

+1

所有的Windows問題都回到了Raymond Chen。 :) 謝謝! – Scott

4

按照MSDN再一個就是允許混合/EHa and /EHsc

兩個異常處理模式,同步和異步,完全兼容,可混在同一個應用程序中。

但是,這條規則似乎有一個例外,那就是將異常從非託管(/ EHsc)傳遞到managed (/clr)。託管代碼使用結構化異常處理(SEH)捕獲所有異常,並且在展開堆棧時導致unmanaged destructors not to be called。有不同的解決方法:

  1. 更改非託管代碼以使用/ EHa而不是/ EHsc。這有一個缺點,那就是在非託管代碼中捕獲(...)突然會發現訪問違規和其他瘋狂的東西。
  2. 在非託管代碼中創建try-catch塊,並確保在非託管世界和託管世界之間不傳遞任何異常。

    2.1。可能的中間道路是確保在從非託管世界向託管世界傳遞異常時,不會調用析構函數。在非託管代碼中創建一個try-catch包裝器,然後在catch-block中將異常重新引入托管的世界。

相關問題