繁体   English   中英

C ++使用异常

[英]C++ using exceptions

我有一个简单的问题

如果我有尝试捕获的代码,像这样

try
{
...
}
catch(exception& ex)
{
   AfxMessageBox(ex.what());
}

这会捕获所有异常,甚至是指针错误等异常吗? 而且,如果此代码存在,例如,该代码具有指针或内存问题,它是否还会崩溃? 还是我必须使用

catch(...)

但是,我该如何准确地确定一次全面崩溃的原因呢?

如果您的代码具有未定义的行为,则可能导致几乎所有事情发生,包括引发异常。

正如您在此处讨论的那样,Visual C ++ 6确实(默认情况下)将某些类似OS的异常转换为C ++异常。 但是,显然效果不是很好-他们的较新的编译器默认情况下不会执行此操作。 如果您确实想要这种行为,他们会提供一个编译器开关(例如/ EHa),让您可以这样做-但大多数人可能不建议您使用它。

Windows结构化异常处理具有SetUnhandledExceptionHandler ,它使您可以捕获SEH异常,对捕获的异常进行排序,并抛出您认为合适的C ++异常来表示发生了什么。 但是,这是一个相当手动的过程(即,您需要编写类似switch语句的内容来整理已捕获的结构化异常,并决定响应该异常而抛出什么C ++异常)。

同样,在Linux上,您可以为各种信号设置处理程序,并抛出异常以响应它们。 不过,您可能需要对此稍加棘手。 问题是,POSIX信号被异步传送,而你你可以在他们做什么限制。 信号处理程序本身几乎唯一可以做的就是设置sig_atomic_t类型的标志,外部代码可以(在方便时)检查其值,如果已设置,则抛出异常。 但是,混合信号和异常通常是一项不平凡的任务。

catch(...)而言,它将仅捕获C ++异常,因此,如果将其与某种转换结合使用,从C ++异常创建C ++异常,则它将仅捕获上述内存问题。结构化异常/信号。 至于您在那可以做什么:确实非常有限。 您根本无法获得有关发生的异常的任何信息。 至少当我使用它时,这几乎是最后一件事,它试图尽可能有序地执行关闭操作,这仅仅是因为在输入时,做任何更明智的事情的可能性就已经存在了。用尽了更多特定的处理程序。

似乎对不同类型的错误感到困惑,因此这里是对不同错误及其处理方法的说明。 可能发生三种错误

  1. 编译错误
  2. 由于触发未定义行为而导致运行时错误
  3. 由于系统限制而导致的运行时错误

这是您需要对这三个进行处理的列表

编译错误您的编译器是您的朋友。 修正您的代码,但请尝试避免绕过类型系统。

触发未定义的行为看起来您的代码中存在这种问题。 在这种情况下,您将遇到运行时错误。 你可能做了什么

  1. 取消引用无效的指针
  2. 用零执行整数除法
  3. 使用了不受支持的程序集级指令
  4. 将已经释放的指针传递给free

要找到解决1-3的问题,可以使用调试器。 assert宏也是有用的。 请注意,可以通过不检查某些分配系统资源的功能是否失败来引入类型1的问题。 如果是这样,请参阅由于系统限制而导致的运行时错误

很难找到类型4的问题,因为您将在下一个malloc注意到该问题。 在GNU / Linux上,通过valgrind运行程序是最安全的选择。 我对Windows工具一无所知。

由于系统限制而导致的运行时错误在这里可以使用异常。 您无法预见到用户指定的文件不存在,或者以不可解码的方式进行了编码。 或者您尝试启动OpenGL,但是用户没有最新的图形驱动程序,或者您处于远程X11连接上。 要“解决”这些问题,您需要检查系统级别的返回值,并通过异常进行纾困,该异常将由最近的catch语句捕获。

std :: exception将仅处理此类异常。 http://en.cppreference.com/w/cpp/error/exception 如果不确定您的try块会抛出哪种异常,而又不想终止进程,则可以盲目地进行catch(...)。 如果您知道您的try块会抛出什么样的异常,并且所有异常都归于std :: exception之下。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM