C++ - Arguments for Exceptions over Return Codes

后端 未结 11 1637
鱼传尺愫
鱼传尺愫 2020-11-29 21:10

I\'m having a discussion about which way to go in a new C++ project. I favor exceptions over return codes (for exceptional cases only) for the following reasons -

相关标签:
11条回答
  • 2020-11-29 21:32

    I think this article sums it up.

    Arguments for Using Exceptions

    1. Exceptions separate error-handling code from the normal program flow and thus make the code more readable, robust and extensible.
    2. Throwing an exception is the only clean way to report an error from a constructor.
    3. Exceptions are hard to ignore, unlike error codes.
    4. Exceptions are easily propagated from deeply nested functions.
    5. Exceptions can be, and often are, user defined types that carry much more information than an error code.
    6. Exception objects are matched to the handlers by using the type system.

    Arguments against Using Exceptions

    1. Exceptions break code structure by creating multiple invisible exit points that make code hard to read and inspect.
    2. Exceptions easily lead to resource leaks, especially in a language that has no built-in garbage collector and finally blocks.
    3. Learning to write exception safe code is hard.
    4. Exceptions are expensive and break the promise to pay only for what we use.
    5. Exceptions are hard to introduce to legacy code.
    6. Exceptions are easily abused for performing tasks that belong to normal program flow.
    0 讨论(0)
  • 2020-11-29 21:32

    Use what makes sense. I think both have a place. There are situations where error codes are nearly impossible to use (returning failure from a constructor, for example)

    Other times, error codes are just more convenient. They're easier to deal with in cases where you expect them to happen. Exceptions are for exceptional errors - the ones that aren't supposed to happen, but might do so once in a blue moon. Error codes are a lot more convenient for errors that are expected to happen regularly, and can be handled locally. Exceptions are most useful in cases where the error must be handled further up the call stack.

    Also, exceptions aren't necessarily faster in the non-exceptional case. Often, they require extra exception handling code in function prolog and epilogs which has to be executed every time the function is called, whether or not it throws an exception.

    0 讨论(0)
  • 2020-11-29 21:33

    It is very hard to write exception safe code. A completely contrived example is :-

    void Class::Method()
    { 
      i++;
      SomeCallThatMightThrow();
      j++;
    }
    

    Replace i++ and j++ with any two variables, resources, states that must remain synchronous. Garbage collection saved us from having to remember to pair our new's and deletes. Ironically, old fashioned explicit return code testing saves us from having to carefully analyse every function that might throw exceptions to check that they havn't screwed with the post-conditions.

    0 讨论(0)
  • 2020-11-29 21:33
    1. Constructors can't give a return code (except if you are possibly throwing exceptions in a constructor you are in for a world of hurt)

    2. Decouples the failure path (which should be very rare) from the logical code which is cleaner (Opens up a much wider failure path. C++ exceptions are not like C# at all. I love C# exceptions. C++ exceptions are worse than useless. Partly due to implementation, partly due to what c++ is and isn't)

    3. Faster in the non-exceptional case (no checking if/else hundreds of thousands of times) (Not really. You have to check the same number of errors no matter what, you just don't see where they get checked. Also, there are errors that matter and ones that don't or at least matter to your code, so you don't have to check every single thing (do you check to see if new threw an error?))
    4. If someone screws up the return code settings (forgets to return FAIL) it can take a very long time to track down. (I'll take a million such errors over any one of the common errors that come about with C++ exceptions)
    5. Better information from the message contained in the error. (It was pointed out to me that a return enum could do the same for error codes) (Well, how do you implement your error handling? That's up to you, isn't it? You can have exceptions that give no useful information or error codes that log out extemsive data on failure. In C++ they seem to never give useful info in the cases you really want them to)
    6. From Jared Par Impossible to ignore without code to specifically designed to handle it (Sure, but this code is usually useless code. It's like passing a law saying everyone has to have bug free programs. The people who don't don't obey such laws anyway and for the people who do they already handle errors where they should anyway)

    As for reasons against:

    1. Wanting your program to actually work at least some of the time.
    2. performance.
    3. Ideology. If it's an error we are not supposed to 'recover' from it. We either die with an error message, log and continue, or completely ignore it. If we could fix it it wouldn't be an error, but a feature...and if you use code like that intentionally no debugging tools in the world are going to save you.

    Mostly one.

    0 讨论(0)
  • 2020-11-29 21:34

    The best case I've heard for preferring return codes over exceptions is simply this:

    1. Writing exception-safe code is hard [in C++].

    With a great deal of recent experience in C# myself, I can empathize with your desire to use exceptions, but unfortunately C++ isn't C#, and a lot of things that we can get away with in C# can be ultimately deadly in C++.

    A good summation of the case for and against can be found in Google's style guidelines. In short:

    Pros:

    • Exceptions allow higher levels of an application to decide how to handle "can't happen" failures in deeply nested functions, without the obscuring and error-prone bookkeeping of error codes.
    • Exceptions are used by most other modern languages. Using them in C++ would make it more consistent with Python, Java, and the C++ that others are familiar with.
    • Some third-party C++ libraries use exceptions, and turning them off internally makes it harder to integrate with those libraries.
    • Exceptions are the only way for a constructor to fail. We can simulate this with a factory function or an Init() method, but these require heap allocation or a new "invalid" state, respectively.
    • Exceptions are really handy in testing frameworks.

    Cons:

    • When you add a throw statement to an existing function, you must examine all of its transitive callers. Either they must make at least the basic exception safety guarantee, or they must never catch the exception and be happy with the program terminating as a result. For instance, if f() calls g() calls h(), and h throws an exception that f catches, g has to be careful or it may not clean up properly.
    • More generally, exceptions make the control flow of programs difficult to evaluate by looking at code: functions may return in places you don't expect. This results maintainability and debugging difficulties. You can minimize this cost via some rules on how and where exceptions can be used, but at the cost of more that a developer needs to know and understand.
    • Exception safety requires both RAII and different coding practices. Lots of supporting machinery is needed to make writing correct exception-safe code easy. Further, to avoid requiring readers to understand the entire call graph, exception-safe code must isolate logic that writes to persistent state into a "commit" phase. This will have both benefits and costs (perhaps where you're forced to obfuscate code to isolate the commit). Allowing exceptions would force us to always pay those costs even when they're not worth it.
    • Turning on exceptions adds data to each binary produced, increasing compile time (probably slightly) and possibly increasing address space pressure.
    • The availability of exceptions may encourage developers to throw them when they are not appropriate or recover from them when it's not safe to do so. For example, invalid user input should not cause exceptions to be thrown. We would need to make the style guide even longer to document these restrictions!

    I suggest reading through and understanding the pros and cons, then making a decision for your own project based on these. You don't have the same software that google has, so what makes sense for them may not make sense for you (which is why I omitted their conclusion).

    0 讨论(0)
  • 2020-11-29 21:35

    One of the things I like about C++ is that it's very easy to think how the higher-level features might be implemented in terms of C features (which are easy to understand in terms of assembly). Exceptions for C++ break this mold. To get this level of understanding I have to do a lot. Just read this and you'll spend a lot of time scratching your head before you understand it.

    Furthermore, exceptions require you to have good discipline making your code exception safe, and resource leak free. This means using RAII for anything that holds a resource ..

    Additionally, exceptions have been shown when I have measured them to be a many, many orders of magnitude slower compared to a simple return code.

    Well then they say you should only throw in exceptional circumstances, but how do you communicate the non-exceptional, expected, often-occuring errors. Well return codes of course! :)

    I don't see how the benefits are worth it.

    0 讨论(0)
提交回复
热议问题