Inline...
-----Original Message-----
From: sweng-gamedev-midnightryder.com-***@lists.midnightryder.com
[mailto:sweng-gamedev-midnightryder.com-***@lists.midnightryder.com]
On Behalf Of Tom Plunket
Sent: Thursday, May 12, 2005 5:34 PM
To: sweng-***@midnightryder.com
Subject: RE: [Sweng-gamedev] Effective use of C++ exceptions
Post by Luis VillegasPeter mentioned something very important, IMHO the main issue
is not only that exception handlers are hard to write, but
I would say the same if it hadn't been said already many times.
:)
Post by Luis Villegas- Your code needs to follow an RAII approach in order to
behave correctly when exceptions are thrown. Note also
that copying objects around needs to be safe in the presence
of exceptions (i.e. copy constructors and assignment
operations)
I don't know that true RAII is necessary, but I do know that
you've got to tear down your objects properly, and not
initializing them properly will make that difficult if not
impossible. ;)
[Luis] Partially agree :-). There are a lot of problems by not doing
true RAII, the init/terminate idiom is error prone, having calls to
"terminate object" inside destructors is error prone, composites are
problematic. But I also understand that true RAII is hard to implement,
in C++ objects that throw during construction never existed, and
constructors for composites are hard to get right and to be exception
safe for true RAII.
Post by Luis Villegas- The components of the engine need to be designed keeping in
mind what are exceptional conditions, and what are expected
error conditions.
This is actually the root of my apprehension about the addition
of exception handling to a game engine. What is an exceptional
condition in games? I mean, we have to handle everything. You
can't just throw up an error box and shut down if the player
pulls controller 1 out of the machine. If you get a CD read
error, you can't well print an error message and abort, either.
I am aligned with the other respondent who said that you've
really got to handle everything locally. I feel very strongly
that errors can not propogate through the system; the file
loader should deal with read errors by retrying a few times.
The model loader should deal with missing assets by putting in
obviously-bad models. The controller code should handle the
missing controller by zeroing the inputs and then waiting for a
reconnect (or hunting for the next controller, depending on
your design requirements). Etc.
Then there are things like normalizing a zero-length vector, or
any number of other degenerations that we see regularly enough
to write "assert()" in. These aren't exceptional either, these
are programming errors, and should probably be handled with
code fixes in the first place, not handling exceptions
generated because of errant code.
[Luis] There are certain things that can be handled locally, and then
you can argue that those things are exceptional or not exceptional
depending on the design. Your design might support trying reads
multiple times in case a read failed, then that becomes non exceptional,
but then you encounter an exceptional case when the max retry count has
been exceeded. What do you do? Do you show a dialog box from your
reading code? (In that case the design has added coupling between the UI
and IO component), do you use error codes and propagate error codes up?
(In such case you are emulating exception propagation using an error
prone technique), you can use exceptions and decouple the reporting from
the reporting code (Being UI or something else), or you can just do
nothing and halt the game which is what happens in many exceptional
cases for console games and that is when they freeze (If you cannot even
load your data for displaying any UI then there is nothing you can do),
in PC you can go back and use the WIN32 APIs to report the problem.
Post by Luis VillegasThe benefit is that in exceptional conditions your application
is on a consistent state and the application can respond
accordingly;
I've found in my own development that exceptions are fun to use
and throw, but that the code isn't really any more readable
because of them. Again, I don't want a texture load failure to
throw an exception that causes the model I'm trying to load to
not come in. I just want the missing texture to be noted in
the log, and have something obviously-wrong on-screen.
[Luis] This is an exceptional case for a shipped game, the customer is
not going to be happy by seeing something obviously-wrong on-screen.
Your texture loader might return a default texture on DEBUG to make
testing easier and to unblock the different disciplines during
development, but it might throw and exception on RELEASE.
Post by Luis Villegas...in real time software most exceptional conditions are fatal
and there is nothing you can do.
I disagree, but only because I don't think there's anything
exceptional (or at least, there shouldn't be) about anything
that happens inside the game engine.
[Luis] Game engines are data driven systems, load and operate on
external data. The engine can get into a state (For internal or
external factors) in which it cannot access the data or in which the
data loaded is bogus, you do not think this is exceptional? The fact
that exceptional conditions can be handled via different techniques
(i.e. error codes) and that the engine can respond to those error codes
in different ways does not make these conditions less exceptional. IMHO
Exceptional conditions are subject to be defined during design, and
different games could consider different situations exceptional
depending on how much they degrade the user experience or how much
functionality is lost by the exceptional case.
Post by Luis VillegasAs far as runtime performance goes in consoles and embedded
systems the cost might be prohibitive...
Until people can show to me that there's a high degree of
probability that everyone on my team can write exception-safe
code in their sleep, I don't care about the performance
implications. ;)
[Luis] Agreed, developer education is one of the biggest problems.
Post by Luis VillegasThe Exceptional C++ series of books cover the requirements
for designing and implementing code with exceptions in mind.
I would agree. It was Herb Sutter's writing that made me
consider the use of exceptions in games to generally be a Bad
Thing in the first place, if only that it was so hard for the
Common Programmer to understand. I mean, if people still
forget to revoke or implement copy semantics for their objects
that need it (or even worse, implement them explicitly for
objects that don't need it), then how can we expect them to
implement their objects in an exception safe manner?
[Luis] Agreed :-)
-tom!