ebmDevMag.com home
ebm Developer's Magazine
links

developer's mag
main page

article
part 1
part 2
part 3
part 4
part 5
part 6
part 7
part 8


3 - Tool #2 - Assertions


As a good programmer (aren't we all?) You've likely been exposed to assert() or a variant. Assert is used to, well, assert something:
  assert(NULL!=ptr); // should never be null!

I've been using a modified version for many years now, called ASSERTING(). After recently reading a chapter on assertions in the book 'Game Programming Gems', I realized it was time to add a few features to the lowly assert, resulting in the following call:
  ASSERTING(int test,const char *message);

Redoing the above example would give you:
  ASSERTING( NULL!=ptr, "should never be null!");

Now, whenever the assertion fails (in this case, when ptr is NULL) the assertion 'fires', and the message "should never be null!" is displayed.

ASSERTING isn't a function, but rather a macro; it actually does quite a bit more than the above call implies:
  • It can be turned off and on - when NDEBUG is defined (see assert2.h), it compiles away to nothing, handy for lean production code.
  • It maintains a memory of where it is, so your assertion message also displays the file and line number of where the assertion is called.
  • It displays three buttons, allowing you to continue execution, turn off the assertion, or quit.

The last feature needs more explanation. Each failed ASSERTING() displays three buttons in a window along with the assertion message: 'Continue', 'Ignore This Assert', or 'Exit Program' ('Break to Debugger' on the emulator). Continue does nothing, which means the assertion will fire each time it is executed and fails. 'Ignore This Assert' allows you to turn off the assertion, preventing future testing. This can be especially useful for loops, where you don't need the repeated assertions.

The third option is what I consider the handiest feature of ASSERTING(). Typical assertions use an abort() call or something similar to exit. More often than not, what you really want to do is look at the offending code in the debugger. When run on the ebm, exiting is the only option, and the program displays 'Exit Program'; but when run on the emulator, the button displays 'Break to Debugger', and will break into the debugger pointing at the ASSERTING() call.

To use ASSERTING(), add assert2.cpp to your makefle, and #include "assert2.h" in your source. Add the call wherever you wish. Remember that ASSERTING() is a macro, and can be compiled out of the code - for that reason always code it as if the line might disappear (because with NDEBUG defined it will!); always put it on a line by itself, and watch out where it is placed. Also avoid side effects - don't do a necessary calculation in the ASSERTING() body, since production code will be lacking that calculation result. Finally, any time you turn on or off NDEBUG, perform a 'make clean', and then 'make', so all source is recompiled with the changes.

Previous Section
Next Section

Copyright © 2001-2006 ebmDevMag.com - Legal Notice