Thread: To Use Exceptions or Not.

  1. #1
    Codebot
    Join Date
    Jun 2004
    Location
    Toronto
    Posts
    195

    To Use Exceptions or Not.

    I am considering the use of exceptions in my Game engine, But I have some problems with it. I know it can be a powerful tool for unexpected errors, but why should i wrap all my code in Try/Catches instead of using detailed return values. The win32 API uses HRESULTS to return specific error codes. Its a brute force way of giving feedback, but requires some sort of look up for error codes.

    Are these my only options for returning a Failure/Success values?

    I also looked into using a state machine for logging/Error checking. It would know what the last error was. unfortunately, this is not thread safe (Any state machine is not thread safe if it crosses thread boundaries, even with proper mutexing).


    Any suggestions/comments are always appreciated. Also I apologize for possibly duplicating some posts, if this was talked about before.
    Founder and avid member of the Internationsl Typo Associateion

  2. #2
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    HRESULTs are not the only way. A better way is to return classes with detailed information.
    Anyway, both methods have their ups and downs. I would consider making the engine return-only since exceptions are very expensive.

    I can suggest that if there's a lot of serial code (lines that depends on the previous lines succeeding), then an exception might be better (since it would skip over all the code so you don't have to check all the lines for errors).
    If it's not this type of code, you might get away with returning errors. It's good to wisely choose a method best for the situation.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  3. #3
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    I know it can be a powerful tool for unexpected errors, but why should i wrap all my code in Try/Catches instead of using detailed return values.
    You should not be wrapping all your code in try/catch blocks. Rather, you should let exceptions propagate until there is sufficient information to handle them correctly, or translate them to exceptions of more appropriate types (but that would involve try/catch, admittedly). Related to this is the fact that one can easily ignore a return code, but ignoring an exception takes more work.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  4. #4
    Codebot
    Join Date
    Jun 2004
    Location
    Toronto
    Posts
    195
    Quote Originally Posted by Elysia
    A better way is to return classes with detailed information.
    I have though about this. Making a very light weight and fast class that would wrap an error code and other information would be very useful. The only problem i see with this approach is that the class could slow the program down if used everywhere. On the other hand, you could use inheritance and derive very detailed message classes, much like you could with c++ exceptions.

    Quote Originally Posted by laserlight
    Related to this is the fact that one can easily ignore a return code, but ignoring an exception takes more work.
    This is a good point. Which makes it very powerful.
    Founder and avid member of the Internationsl Typo Associateion

  5. #5
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    The only problem i see with this approach is that the class could slow the program down if used everywhere.
    Consider that the cost of an exception is only incurred when it is thrown, but the cost of such a message object is incurred whether or not there is an error.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  6. #6
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Quote Originally Posted by Mastadex View Post
    The only problem i see with this approach is that the class could slow the program down if used everywhere.
    I don't really see a problem. It would still be blazing fast. Plus if you make the class functions small enough, the compiler will likely inline them.
    Or if you really want, you can return a pointer to an error class, or NULL if success.
    It practically combines the best of both traits. Oh, and combine that with a memory pool and you get a powerful exception concept with small overhead.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  7. #7
    Frequently Quite Prolix dwks's Avatar
    Join Date
    Apr 2005
    Location
    Canada
    Posts
    8,057
    Or if you really want, you can return a pointer to an error class, or NULL if success.
    And how do you handle out-of-memory errors?
    dwk

    Seek and ye shall find. quaere et invenies.

    "Simplicity does not precede complexity, but follows it." -- Alan Perlis
    "Testing can only prove the presence of bugs, not their absence." -- Edsger Dijkstra
    "The only real mistake is the one from which we learn nothing." -- John Powell


    Other boards: DaniWeb, TPS
    Unofficial Wiki FAQ: cpwiki.sf.net

    My website: http://dwks.theprogrammingsite.com/
    Projects: codeform, xuni, atlantis, nort, etc.

  8. #8
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Throw an exception? That's typically what new does anyway, so you're still safe, I'd assume.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  9. #9
    Frequently Quite Prolix dwks's Avatar
    Join Date
    Apr 2005
    Location
    Canada
    Posts
    8,057
    I was just pointing out that your scheme, which presumably involves allocating space for an error class to return it, would not be able to handle certain types of errors. (BTW: you're probably right; throwing an exception is likely a good idea when you run out of memory.)

    Your idea also suffers from the same problem that other return-value ones do. You have to check the return value. As laserlight said, it's easy to ignore a return value. (How many of us check the return value of printf()?) You're also neglecting one of the largest advantages of exceptions: they can be handled at any point in the call stack.

    But anyway. There's nothing wrong with using return values -- I usually do myself -- but you just have to remember that it isn't perfect.
    Last edited by dwks; 08-15-2008 at 02:35 PM. Reason: re-organized, hopefully it's less confusing now
    dwk

    Seek and ye shall find. quaere et invenies.

    "Simplicity does not precede complexity, but follows it." -- Alan Perlis
    "Testing can only prove the presence of bugs, not their absence." -- Edsger Dijkstra
    "The only real mistake is the one from which we learn nothing." -- John Powell


    Other boards: DaniWeb, TPS
    Unofficial Wiki FAQ: cpwiki.sf.net

    My website: http://dwks.theprogrammingsite.com/
    Projects: codeform, xuni, atlantis, nort, etc.

  10. #10
    Codebot
    Join Date
    Jun 2004
    Location
    Toronto
    Posts
    195
    Quote Originally Posted by dwks View Post
    And how do you handle out-of-memory errors?
    I believe at this point A lot of applications will be crashing due to memory limitations and if mine crashes, it's not so bad. But this case is quite rare with Virtual memory and stuff that I doubt its something to worry about. Also, the way I have my program set up is that I use either placement new for memory on heap memory or I use new(std::nothrow) so that when an error occurs it returns a NULL pointer, which is always handled in my code (Yes, I'm a nazi for this).
    Founder and avid member of the Internationsl Typo Associateion

  11. #11
    Registered User
    Join Date
    Jul 2003
    Posts
    110
    Quote Originally Posted by Mastadex View Post
    I also looked into using a state machine for logging/Error checking. It would know what the last error was. unfortunately, this is not thread safe (Any state machine is not thread safe if it crosses thread boundaries, even with proper mutexing).
    Wait! Don't throw this option out yet, especially if your engine is going to be mostly event driven.

    You are right that a state machine should not cross thread boundaries, but that is not a limitation IMO. In my experience, it can actually be a benefit that helps to maximize concurrency and results in less contention.

    The reason you posted your question is error handling though, and I think state machines for an event driven program are a far better mechanism than C++'s built-in exception handling. For no other reason, than you get state-based exception handling! Also, operations that you are coding are done while much more is known about the state of the system, so you are much more likely to be able to ignore certain outcomes since you already know much more information due to the state-based architecture. IOW, you already know the conditions of the system, so you can filter potential error returns much more deterministically.

    I probably go too far in my argument, but state machines are ignored and neglected too often IMO. I'd suggest reconsidering your thread safe argument, because they can be very favorable to concurrent systems if you rethink the traditional approach of 'acquire-lock, do-work, release-lock'. It's a big paradigm shift, but it is totally worth it.

    You might try this site for a great idea regarding hierarchical state machines that are designed to be used in multi-threaded systems that are primarily event-driven (which, again, is where state machines truly shine, and should be the default architecture IMO):

    http://www.state-machine.com/

    ...its emphasis is on embedded programming, but I have used this pattern successfully in applications for Linux and Windows. It's worth a look, you will get alot more than just a good error handling design. Again, though, this is only really true if your engine is event driven, but what games aren't?

  12. #12
    Algorithm engineer
    Join Date
    Jun 2006
    Posts
    286
    whoie, why does state machines work best for event-driven programs?

    Elysia, I assume you mean returning class objects of a certain class? I don't really see the point with using a memory pool. IMO, you either return actual objects (which would give you the highest degree of freedom in specifying the error), or you return a pointer to an standard error object being created at program start up; why would you want to keep an error object, which was created somewhere in the middle of the program execution, in a memory pool?
    Come on, you can do it! b( ~_')

  13. #13
    Registered User
    Join Date
    Jul 2003
    Posts
    110
    Quote Originally Posted by TriKri View Post
    whoie, why does state machines work best for event-driven programs?
    Great question! I'm afraid I would be threadjacking if I gave a complete answer, so in short, the traditional approach to event driven systems i.e. event->action does not have much room to take into account the current condition of the system without a series of flags and booleans and complex conditional expressions. State machines avoid that, and are naturally good at dealing with asynchronous events.

    When I get some time, I'll post some stuff I did about a year ago with a simple hierarchical state machine template. That way we can have a good discussion about it without diverting from the topic of this thread!

  14. #14
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Quote Originally Posted by TriKri View Post
    Elysia, I assume you mean returning class objects of a certain class? I don't really see the point with using a memory pool. IMO, you either return actual objects (which would give you the highest degree of freedom in specifying the error), or you return a pointer to an standard error object being created at program start up; why would you want to keep an error object, which was created somewhere in the middle of the program execution, in a memory pool?
    The idea with a memory pool is to allocate small amounts of data faster than new, not keep them alive.
    Creating an error object at startup and reusing is certainly an idea, but it, too, has limitations. It depends on what you want to do.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Are Exceptions effective?
    By Petike in forum C++ Programming
    Replies: 5
    Last Post: 09-13-2008, 12:23 AM
  2. Intercepting Fortran exceptions
    By MarkZWEERS in forum C++ Programming
    Replies: 2
    Last Post: 08-06-2008, 09:13 AM
  3. Debug --> Exceptions in Visual Studio 2005
    By George2 in forum C# Programming
    Replies: 1
    Last Post: 08-10-2007, 02:12 AM
  4. Need advice: catch exceptions or call methods to check bits?
    By registering in forum C++ Programming
    Replies: 1
    Last Post: 10-03-2003, 01:49 PM
  5. Throwing exceptions with constructors
    By nickname_changed in forum C++ Programming
    Replies: 14
    Last Post: 07-08-2003, 09:21 AM