C++ - Arguments for Exceptions over Return Codes

后端 未结 11 1638
鱼传尺愫
鱼传尺愫 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:40

    IMHO, the #1 reason to prefer exceptions over return codes is you can't silently ignore an exception. Doing so requires at least a minimum amount of extra code.

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

    As a general rule. when recovery is possible and expected then use return codes.

    When recovery is not possible or not desired then use exceptions.

    Error handling is difficult, writing clean code with and without exceptions is - difficult.

    As this is a new project, you don't have to worry about making old code exception safe, however you do have to worry about writing clean clear code.

    Do so by using exceptions where appropriate.

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

    Faster in the non-exceptional case (no checking if/else hundreds of thousands of times)

    In the non-exceptional case, it's a single comparison to determine that E_SUCCESS was returned.

    If someone screws up the return code settings (forgets to return FAIL) it can take a very long time to track down.

    If someone fails to check the exceptions, it can be difficult to notice until you actually get an exception thrown there. If you're dealing with error codes, you know just by looking at it whether they're checking for them or not.

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

    Since many others have already provided the technical reasons for using exceptions over error codes, I will give a practical one.

    I work on a complex system which uses return codes instead of exceptions. Now, this is very well designed code, but I would bet that, on average, about 70% of the code in every function is error handling code. A typically function looks something like this:

    long Foo( )
    {
        long retCode = MoveStage( );
        if ( retCode != RetCode_OK )
        {
            logger->LogError( __LINE__, __FILE__, "some message" );
            return( retCode );
        }
    
        int someConfigVar = 0;
        long retCode = GetConfigVar( "SomeVarName", someConfigVar );
        if ( retCode != RetCode_OK )
        {
            logger->LogError( __LINE__, __FILE__, "some message" );
            return( retCode );
        }
    
        long retCode = DoSomething( );
        if ( retCode != RetCode_OK )
        {
            logger->LogError( __LINE__, __FILE__, "some message" );
            return( retCode );
        }
    
        // and on and on and on...
    }
    

    The code is full of this and is hard to follow. On top of that, in many places the return code is ignored completely because we know that the call will not fail. Every function returns a ret code, so what you would normally return as the output of the function has to be returned as an out parameter. Also, all of these functions just return the retCode on error, so we just bubble that damn retCode to the top if something bad happens. You cannot centralize your error handling strategy this way, it becomes a messy headache.

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

    Use exceptions for exceptional error conditions. You have some good arguments for, and I'd like to attack some arguments against.

    First, the standard C++ library uses exceptions itself, all over the place. You can't use container classes or iostreams without having them present. Since a lot of the useful features are going to use them, trying to get along without them is going to present a lot of problems.

    Second, it isn't hard to write exception-safe code once you've learned how to do it. It requires consistent RAII, but that's how you should write anyway. You should adopt a construct-commit approach, but that is frequently an advantage, and avoids some subtle bugs. (For example, the self-assignment problem disappears entirely with a copy-swap approach.) In my experience, exception-safe code looks better in general. It is something C++ programmers have to learn, but there's lots of things C++ programmers have to learn, and this isn't that much more.

    Third, provided you limit exceptions to exceptional cases, there should be minimal effects on performance. And, as Pavel Minaev has pointed out, if you have to pass error codes back with results, there's the possibility of effects on performance, since C++ isn't set up for easy returns of multiple values.

    Fourth, it is indeed difficult to make older code exception-safe. However, this is a new project.

    So, I see no good reasons not to throw exceptions in exceptional circumstances, and plenty of reasons to do so.

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