簡體   English   中英

為什么我的C ++異常沒有被捕獲?

[英]Why are my C++ exceptions not being caught?

我有一些使用非常標准的異常模式的C ++代碼:

try {
  // some code that throws a std::exception
}
catch (std::exception &e) {
  // handle the exception
}

問題是異常沒有被捕獲,我無法弄清楚原因。

代碼編譯為OS X中的靜態庫(通過Xcode)。 該庫鏈接到一個Cocoa應用程序,通過Objective-C ++ thunk調用所討論的函數。 我懷疑Objective-C和C ++之間的相互作用是罪魁禍首,但我所有試圖將其解決的嘗試都失敗了。

我無法創建一個簡單的示例,在一個簡單的示例中重現此行為。 當我從大型程序的上下文中取出相關代碼時,一切正常。

任何人都可以建議為什么我的例外沒有被抓住?

嘗試一個catch(...) {}塊,看看是否真的拋出異常。

C ++允許您使用各種選項來捕獲:值,引用或指針。 請注意,此代碼僅捕獲通過引用或值傳遞的std :: exceptions:

try {
  // some code that throws a std::exception
}
catch (std::exception &e) {
  // handle the exception
}

指針可能會傳遞異常:

catch (std::exception* e)

檢查拋出異常的代碼,看看它是如何做的。

正如馬克指出的那樣,如果你按價值而不是通過參考捕獲,你就有可能切割你的對象。

我懷疑Objective-C和C ++之間的相互作用是罪魁禍首,但我所有試圖將其解決的嘗試都失敗了。

你可能是對的,雖然很難找到。

首先,GCC明確地不允許你在Objective C ++中拋出異常並用C ++捕獲它們 (“當從Objective-C ++使用時,Objective-C異常模型此時不與C ++異常互操作。這意味着你不能@throw Objective-C的一個例外,用C ++ catch它,反之亦然(即throw ... @catch )。“)

但是,我認為您正在描述一個Objective C ++調用C ++代碼,C ++代碼拋出並且您希望C ++代碼捕獲異常的情況。 不幸的是,我很難找到這個具體案例的文檔。 有一些希望因為,“ 通過為Java異常模型編譯的另一個文件從一個文件拋出C ++異常被認為是安全的,反之亦然,但這個領域可能存在缺陷 。” 如果他們可以為Java做,那么他們有可能為Objective C ++做到這一點。

至少,您需要在編譯時指定-fexceptions (“在編譯需要與使用C ++編寫的異常處理程序正確互操作的C代碼時,您可能需要啟用此選項”)。 同樣,這並沒有特別提到Objective C ++,但它可能適用。

一個鮮為人知的問題與異常有關,與基類的訪問有關。

如果你實際上拋出了一個私有地從std::exception派生的類,那么將不會選擇std::exception處理程序。

例如:

#include <iostream>

class A { };
class B : private A { } ;

int main ()
{
  try
  {
    throw B ();
  }
  catch (A & )
  {
    std::cout << "Caught an 'A'" << std::endl;
  }
  catch (B & )
  {
    std::cout << "Caught an 'B'" << std::endl;
  }
}

通常,這樣的處理程序順序會導致'B'處理程序永遠不會被選中,但在這種情況下'B'私有地從'A'進行處理,因此不考慮類型'A'的catch處理程序。

我可以提供兩種理論:

  1. 異常會在它的catch子句出現之前被捕獲; 堆棧上的任何函數都可能是罪魁禍首。 正如邁克爾所建議的那樣
  2. 異常展開無法找到您的處理程序。 要更詳細地分析這一點,您必須逐步執行異常展開代碼,這非常多毛。 查看使用-fobjc-exceptions幫助編譯Objective-C代碼。

這可能是一個長鏡頭,但在Visual Studio的編譯器設置中,有一個選項可以完全關閉異常。 也許在GCC / XCode中有類似的東西。

C ++異常可以是幾乎任何東西,通常是char* 正如之前所建議的,添加catch (...)至少讓它打破並看看發生了什么。

感謝大家的投入。 對於遇到類似問題的人來說,這些都是很好的建議。 它現在正在運作,但我並不是100%確定我做出的各種改變使得事情再次變得健全。 再次,簡化為有效的東西和從那里建立備份的方法得到了回報。

響應中沒有提到的一件事,我認為是我的困惑的一部分,是確保處理程序明確表明它實際上捕獲了異常。 我認為在我的處理程序的一些配方中,它掩蓋了這個事實並將異常傳遞給更高級別的處理程序。

暫無
暫無

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

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