How far to take error checking?

Started by
12 comments, last by hellz 20 years, 4 months ago
Thanks for the replies guys. Got quite a lot to go on there, and yes PaulCesar, that''s pretty much where I was heading with my question.

I''m thinking about downloading a 3D engine to have a look at; not necessarily for the 3D side of things, but more for the error handling at this point.

There were actually two reasons my question came up:

1. From working on the class I pasted into my original post.
2. Seeing how errors are returned from Unreal Tournament by their calling function(s), as in:

Exception at: MainLoop->GameEngine->Botpack->Warshell->etc.

Some of the error messages I''ve seen from UT have been absolutely huge (message boxes literally taking up an entire screen on 800x600).

Anyway, thanks again. I''ll have a nose around some engine code in a day or so.

-hellz
Advertisement
UT uses the exception mechanism to build those error messages. They have 2 macros, guard and unguard:

SomeObject::SomeFunc(){   guard(SomeObject::SomeFunc)   // code   unguard;}


The guard macro starts the try block, but also stores the name of the function in a local static variable (and possible some other stuff). The unguard macro closes the try and implements the catch block. When an exception is caught, the function name in the local var is added to a list somewhere and the exception is rethrown. The function names in the list are then used to build a stack trace.

Additionally, two other versions of the macros, guardslow and unguardslow, are used in performance critical areas. These macros can be turned on for testing/debugging purposes, but are turned off in the release version.

The Torque engine takes a somewhat different approach, using a custom assert system. This is used most often to verify function params, but also to catch things like ''divide by zero'' and ''array out of bounds''. There are different macros for fatal and warning conditions, and also macros for release build and those that are turned on/off for testing and debugging. This sort of system can also be implemented in C.

Error checking can take away cycles, but it is important nonetheless. People who knock Java & C# often point at the fact that they are not compiled to native code as a reason for performance issues, when in fact it''s mostly because of all of the error checking going on behind the scenes. Those languages verify that every array access is in bounds, that every divide is safe, and things other than error checking. C and C++ allow you to be as stringent or as loose about error checking as you''d like, which is a great thing when performance is important.

I think a simple rule to follow is, write your code to check for errors everywhere the code can hurt you (verifying function params, return values, array indices where they may go out of bounds, etc...). Remove the checks that hurt performance only after profiling, but see if there are other ways of making the same check without the performance penalty (verifying a pointer once before calling a method multiple times, rather than in the method itself, for example). Also, if the game is moddable, it may be a good idea to look for optimizations elsewhere and leave the error checking code in if it''s something that can be unpredictable at runtime. Macros can greatly help in this, so they can be turned on and off when needed.
Wow, thanks for the reply, Aldacron. That''s given me quite a nice insight and a lot of food for thought.

Thank you very much.

-hellz
quote:Original post by Nekhmet
I think exceptions should only be used if the error is recoverable.

For example, let''s say that your loadBMP fails. What are you going to do... play the game without the bitmap? Is that really acceptable? If you can''t play without the bitmap, then it''s easiest to just display an error and stop the game.



But you can do that with an exception. Just catch fatal exceptions at the top level, cleanup, and bail.


--
Dave Mikesell Software & Consulting

This topic is closed to new replies.

Advertisement