为什么异常处理不好? [英] Why is exception handling bad?

查看:126
本文介绍了为什么异常处理不好?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

Google的Go语言作为设计选择没有例外,Linux的Linus称为异常。为什么?

Google's Go language has no exceptions as a design choice, and Linus of Linux fame has called exceptions crap. Why?

推荐答案

异常使得写入代码非常容易,抛出异常将会破坏不变量并使对象处于不一致的状态。他们基本上强迫你记住,你所做的大部分声明都可能会抛出,并正确处理。这样做可能是棘手和反直觉的。

Exceptions make it really easy to write code where an exception being thrown will break invariants and leave objects in an inconsistent state. They essentially force you to remember that most every statement you make can potentially throw, and handle that correctly. Doing so can be tricky and counter-intuitive.

将这样的事情看作一个简单的例子:

Consider something like this as a simple example:

class Frobber
{
private:
    int m_NumberOfFrobs;
    FrobManager m_FrobManager;

public:

    void Frob()
    {
        m_NumberOfFrobs++;

        m_FrobManager.HandleFrob(new FrobObject());
    }
};

假设 FrobManager 删除 FrobObject ,看起来不错,对吧?或者也可能没有...想象一下,如果 FrobManager :: HandleFrob() operator new 抛出异常。在此示例中, m_NumberOfFrobs 的增量不会回滚。因此,任何使用 Frobber 的实例的人将会有一个可能损坏的对象。

Assuming the FrobManager will delete the FrobObject, this looks OK, right? Or maybe not... Imagine then if either FrobManager::HandleFrob() or operator new throws an exception. In this example, the increment of m_NumberOfFrobs does not get rolled back. Thus, anyone using this instance of Frobber is going to have a possibly corrupted object.

此示例可能看起来很愚蠢(好的,我不得不伸展自己,构造一个:-)),但是,外带的是,如果一个程序员不是一直在思考异常,并确保每一次排列的状态都会被抛回这样你就会遇到麻烦。

This example may seem stupid (ok, I had to stretch myself a bit to construct one :-)), but, the takeaway is that if a programmer isn't constantly thinking of exceptions, and making sure that every permutation of state gets rolled back whenever there are throws, you get into trouble this way.

举个例子,你可以像想到互斥体一样想到它。在一个关键部分,你依靠几个语句来确保数据结构没有被破坏,而其他线程看不到你的中间值。如果这些言论中的任何一个随机都没有运行,那么你最终会陷入痛苦的世界。现在拿走锁和并发,并考虑每一种方法。将每个方法视为对象状态的排列事务,如果你愿意的话。在方法调用开始时,对象应该是清洁状态,最后还应该有一个干净的状态。之间,变量 foo 可能与 bar 不一致,但您的代码最终会纠正。什么例外意味着任何一个你的声明可以在任何时候打断你。在这种情况下,每个单独的方法都可以让你正确地回滚,或者命令你的操作,所以抛出不会影响对象状态。如果你错了(这很容易犯这种错误),那么调用者最终会看到你的中间值。

As an example, you can think of it like you think of mutexes. Inside a critical section, you rely on several statements to make sure that data structures are not corrupted and that other threads can't see your intermediate values. If any one of those statements just randomly doesn't run, you end up in a world of pain. Now take away locks and concurrency, and think about each method like that. Think of each method as a transaction of permutations on object state, if you will. At the start of your method call, the object should be clean state, and at the end there should also be a clean state. In between, variable foo may be inconsistent with bar, but your code will eventually rectify that. What exceptions mean is that any one of your statements can interrupt you at any time. The onus is on you in each individual method to get it right and roll back when that happens, or order your operations so throws don't effect object state. If you get it wrong (and it's easy to make this kind of mistake), then the caller ends up seeing your intermediate values.

像RAII这样的方法,C ++程序员喜欢提到这个问题的最终解决方案,要做好防范措施。但他们不是一个银弹。它将确保您释放资源,但不会让您无需考虑对象状态的损坏和看到中间值的呼叫者。所以,对于很多人来说,通过编码风格的说法,比较容易,没有例外。如果您限制您编写的代码类型,那么很难介绍这些错误。如果你不这样做,这是一个很容易的错误。

Methods like RAII, which C++ programmers love to mention as the ultimate solution to this problem, go a long way to protect against this. But they aren't a silver bullet. It will make sure you release resources on a throw, but doesn't free you from having to think about corruption of object state and callers seeing intermediate values. So, for a lot of people, it's easier to say, by fiat of coding style, no exceptions. If you restrict the kind of code you write, it's harder to introduce these bugs. If you don't, it's fairly easy to make a mistake.

整本书已经写在C ++中的异常安全编码。很多专家错了。如果它真的那么复杂,有这么多的细微差别,也许这是一个很好的迹象,你需要忽略这个功能。 : - )

Entire books have been written about exception safe coding in C++. Lots of experts have gotten it wrong. If it's really that complex and has so many nuances, maybe that's a good sign that you need to ignore that feature. :-)

这篇关于为什么异常处理不好?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆