2011-03-22 51 views
1

在谈论错误处理时,我有点困惑。例如,以Direct2D为例。 之前,我们可以开始使用Direct2D的功能,我们必须创建一个ID2DFactory对象:关于编程中的通用错误处理的问题

HRESULT hr = D2D1CreateFactory(D2D1_FACTORY_TYPE_SINGLE_THREADED, &d2d1Factory); 

正如你可以看到从上面。我们可以检查HRESULT hr以查看我们是否成功创建了ID2DFactory。 我认为当这个调用失败时,即使我再次调用它,仍然失败。我们没有任何方法可以从此故障中恢复。

那么检查返回值有什么意义?是否可以在终止程序之前告诉用户出了什么问题?

另一个例子是内存不足。当我们遇到罕见的情况时,我们没有足够的记忆来让我们的程序“新”一些对象。 在C++中,当运行内存不足时,new运算符可能会返回NULL或引发错误。如果您没有测试它是否为NULL并且没有发现错误,那么程序将终止。我认为你的程序不能从这种情况中恢复过来。

那么,检查是否存在一个严重的错误,你无能为力?

回答

1

像D2D1CreateFactory()这样的初始化函数可能会失败。这种故障通常意味着您的PC上的操作系统已完全损坏,您需要重新启动。这些信息对于用户来说很有价值,他们想知道“O/S是否被洗掉,重新启动并重试”与“在模块mod.c中类似2345处取消引用无”。如果你不抓住错误条件,你所有的用户都知道程序崩溃了。

捕获错误返回和异常,并将它们报告给用户是将好程序和差程序分开的许多事情之一。

特别是对于新的程序,您的程序通常有很多选项。它可能能够重新请求一个较小的初始内存块。它可能会返回内存缓存值,然后再试一次。它可以保存文件以准备退出,这也具有返回内存的效果。

当您处理错误返回或异常时,您有四个选择;中止,交替,重试,失败。

放弃是清理并退出;最好是返回资源,关闭文件和保存在制品。

交替尝试一种完全不同的方法来做同样的事情;像尝试ftp,如果你不能使用http。交替是最难的错误恢复方法,坦率地说,大多数情况下,只有美国国家航空和航天局有预算来编写这种错误处理。

重试是简单地再次尝试相同的操作。如果失败是暂时的,这可能是成功的。如果故障持续存在,重试会导致无限循环,因此重试最好使用限制计数器或指数级增加的时间延迟。

失败是简单地删除请求或操作并尝试处理下一个请求。失败可能看起来很愚蠢,因为这意味着未执行请求,屏幕未更新,或用户输入被忽略。但令人惊讶的是,用户可以通过在程序外执行某些操作来恢复这种错误,或者在情况不同的情况下再次尝试。在大多数情况下,如果程序终止,它会完全拒绝用户的服务,用户可能能够使用已损坏或部分正确的程序。 (尝试想象一个飞行控制系统因为它被解除引用而放弃,这不是你想要的。)

4

首先,不是每个错误都无法恢复。例如:如果文件用户想要打开的文件不可用,程序可能想要将此报告给用户并要求另一个文件打开。第二,即使程序不能继续,它也必须有机会正常终止,告知用户有关问题,保存状态,记录问题以备将来分析等,而不仅仅是崩溃。没有错误检查,程序很可能会崩溃。

+1

+1,错误报告是非常重要的。简单的例子:想象一下,如果你的代码不正确,编译器会崩溃......错误报告的质量往往是底层程序质量的指标。 – 2011-03-22 18:31:32

2

曾经有客户说过“它刚刚崩溃”的错误报告?当错误报告包含错误对话框的屏幕截图,说明“D2D1CreateFactory返回E_...”时,它们会更有用。

0

可能有很多东西需要像打开的文件句柄一样清理,或者某些数据库操作需要在出错时执行回滚等。在某些情况下,错误可能并不重要,程序可能只能继续使用部分功能,而不是完全崩溃。最后但并非最不重要的是,它提供了有关发生错误的有价值的信息,这对调试非常有用。

顺便说一句,除非你使用的是一些古代编译器不符合,new不能按照C++标准返回NULL,否则在发生故障时必须抛出std::bad_alloc异常。

0

检查返回值,这对调试是非常重要的。只需使用它的宏。

0

图像两个程序,每个程序都会遇到错误。

由于内存不足或其他原因导致内存崩溃,导致非法使用内存,操作系统显示一些模糊的错误,或者只是默默关闭程序。

其他应用程序显示更简单的错误消息,然后回滚导致错误的操作,以便您可以决定是否要继续和/或尝试解决导致错误的条件。 (例如,也许关闭一些其他应用程序将允许有更多的内存。)

您宁愿使用哪个程序?