为什么我的C ++异常没有被捕获?

时间:2009-09-04 06:03:37

标签: c++ objective-c exception-handling

我有一些使用非常标准的异常模式的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 ++之间的相互作用是罪魁祸首,但我所有试图解决这个问题的尝试都失败了。

我无法在一个简单的示例中创建一个简单的示例来重现此行为。当我从大项目的上下文中取出相关代码时,一切正常。

有人能说明为什么我的例外没有被抓住吗?

8 个答案:

答案 0 :(得分:16)

尝试catch(...) {}阻止,看看是否真的抛出异常。

答案 1 :(得分:16)

C++ allows you a variety of options for catching: value, reference or pointer. 请注意,此代码仅捕获通过引用或值传递的std :: exceptions:

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

异常可能是由指针传递的:

catch (std::exception* e)

检查抛出异常的代码,看看它是如何做的。

正如马克指出的那样,如果你按价值而不是按参考来捕捉,你就有可能切割你的物体。

答案 2 :(得分:7)

  

我怀疑Objective-C和C ++之间的相互作用是罪魁祸首,但我所有试图将其解决的尝试都失败了。

你可能是对的,虽然很难找到。

首先,GCC显式does not allow you to throw exceptions in Objective C++ and catch them in C++(“当从Objective-C ++使用时,Objective-C异常模型此时不与C ++异常互操作。这意味着你不能@throw来自Objective的异常-C和catch它在C ++中,反之亦然(即throw ... @catch)。“)

但是,我认为您正在描述一个Objective C ++调用C ++代码,C ++代码抛出并且您希望C ++代码捕获异常的情况。不幸的是,我很难找到这个具体案例的文档。有一些希望,因为,“It is believed to be safe to throw a C++ exception from one file through another file compiled for the Java exception model, or vice versa, but there may be bugs in this area。”如果他们可以为Java做,那么他们有可能为Objective C ++做这件事。

至少,您需要在编译时指定-fexceptions(“在编译需要与使用C ++编写的异常处理程序正确互操作的C代码时,您可能需要启用此选项”)。同样,这并没有特别提到Objective C ++,但它可能适用。

答案 3 :(得分:5)

一个鲜为人知的有异常的问题与基类的访问有关。

如果您实际上正在抛出一个私有派生自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'进行处理,因此类型的catch处理程序' A'不予考虑。

答案 4 :(得分:3)

我可以提供两种理论:

  1. 异常会在catch子句出现之前被捕获;堆栈上的任何函数都可能是罪魁祸首。正如迈克尔所建议的那样,尝试捕捉一切。
  2. 异常展开无法找到您的处理程序。要更详细地分析这一点,您必须逐步执行异常展开代码,这非常多毛。查看是否使用-fobjc-exceptions帮助编译Objective-C代码。

答案 5 :(得分:1)

这可能是一个很长的镜头,但在Visual Studio编译器设置中,有一个选项可以完全关闭异常。也许在GCC / XCode中有类似的东西。

答案 6 :(得分:0)

C ++异常几乎可以是任何事情,通常是char*。正如之前所建议的那样,添加catch (...)至少让它打破并看看发生了什么。

答案 7 :(得分:-2)

感谢大家的投入。对于遇到类似问题的人来说,这些都是很好的建议。它现在正在运作,但我并不是100%确定我做出的各种改变使得事情再次变得健全。再一次,简化为有效的东西并从那里建立备份的方法得到了回报。

响应中没有提到的一件事,我认为是我的困惑的一部分,是确保处理程序明确表明它实际上捕获了异常。我认为在我的处理程序的一些配方中,它掩盖了这个事实并将异常传递给更高级别的处理程序。