繁体   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