2

I'm making a c++ game gui lib and wondering when i should be throwing exceptions. Right now, for example, if I get a NULL pointer, the function silently fails. Should I instead throw an exception? Its not something that would really cause it to crash though. What are some examples of good places to throw exceptions?

thanks

jmasterx
  • 52,639
  • 96
  • 311
  • 557
  • 4
    Anything is better than silently failing. – James McNellis Nov 02 '10 at 00:15
  • 1
    If you're writing a library, you may want to reuse it in future or distribute it to friends / colleagues. Personally, I throw exceptions all over the place to give me the flexibility of handling it or ignoring it in the end application, as opposed to silently failing in the library. – dotalchemy Nov 02 '10 at 00:19
  • Better is why you're using a pointer instead of a reference, especially if you must be referring to a valid object. – GManNickG Nov 02 '10 at 00:29
  • because it is a void pointer thats reinterpreted – jmasterx Nov 02 '10 at 00:33
  • First, that should probably be a static cast, not reinterpret cast, and second you shouldn't allow the possibility for that void pointer to hold null. Of course, a concrete example solves all questions. – GManNickG Nov 02 '10 at 00:35
  • Third, why is your C++ program using void pointers? (If it's due to interaction with a legacy or third-party API, then that's okay, but beyond that, there are few good uses of void pointers in C++) – James McNellis Nov 02 '10 at 00:38
  • 1
    A base `IUserData` class would be better; then you can safely cast to derived types using `dynamic_cast`. This is the approach used, for example, by OpenSceneGraph. – James McNellis Nov 02 '10 at 01:00
  • I think this is a duplicate of: [When to throw an exception](http://stackoverflow.com/questions/77127/when-to-throw-an-exception) – Marc Butler Nov 02 '10 at 01:03

4 Answers4

11

The usual answer to this question is that you should only throw exceptions in 'exceptional' circumstances. But what are exceptional circumstances. Some examples:

  • Events outside of your control (e.g. out of memory, missing file)
  • Illegal parameters passed to your methods (i.e. you specify your method requires a handle and the caller passes null)

It's generally a bad idea to throw exceptions as part of the normal flow of the application, but again it's up to you to define what the normal flow of the application is. But one way of looking at it is that your API should specify the range of valid inputs it will accept - and you shouldn't throw an exception in response to those inputs.

This topic has been covered a great deal on this site and elsewhere so a google search using your title will throw up lots more examples and comments.

With regards your specific application - maybe get a hold of the api for some other game gui libs to get a feel for how these libs work (assuming you think they are well designed).

James Gaunt
  • 14,631
  • 2
  • 39
  • 57
3

Very generally: throw an exception when something exceptional happens. In your example, if null is acceptable input with defined behaviour then don't throw an exception. If null is illegal input then you should throw an exception to indicate to the caller that something has gone wrong.

Cameron Skinner
  • 51,692
  • 2
  • 65
  • 86
0

It fully depends on what you doing and what you want use your code in future.

You should throw exception when something was fail and you don't have any options or technically this will be not optimal to try repair this situation; in other words point when from your point of view is a problem.

Silent failing is a worst idea who i hear if you talking about library writing.

Svisstack
  • 16,203
  • 6
  • 66
  • 100
0

You have to report some kind of failure. You can do this with exceptions or status codes. Personally, I lean toward status codes if possible, especially in library code.

There was once a time that you couldn't be sure that an exception would actually be caught unless the code doing the catching was built by the same version of the same compiler with the same flags as the code throwing the exception. That seems to have been largely solved on platforms that have a de facto standard ABI. But once I got used to reporting failures in library code without exceptions I found that there are valid reasons to continue to do so.

For one, libraries are meant to be used by third parties, and those parties may not be all too excited about writing exception safe code.

Exception safe code isn't only about resource management. Consider:

...
// m is a mutex
boost::scoped_lock(m); // now I can't forget to release the mutex
withdraw_money(acct1, 1000);
function_that_may_throw_exception();
deposit_money(acct2, 1000);

Of course it's possible to rewrite this:

// using Boost SCOPE_EXIT
bool commit = false;
boost::scoped_lock(m);
withdraw_money(acct1, 1000);
SCOPE_EXIT((&commit) (&acct1))
{
    if (!commit) {
        deposit_money(acct1, 1000);
    }
}

function_that_may_throw_exception();
deposit_money(acct2, 1000);
commit = true;

Exceptions solve many problems, but they don't solve all problems associated with error handling/detection. Writing invalid code is just as possible with exceptions as it is with status codes.

Max Lybbert
  • 19,717
  • 4
  • 46
  • 69