eyt*
Jun 09, 2004

Minefields...

In The Inmates Are Running the Asylum, Alan Cooper says that Stalin would clear minefields by sending a regiment marching through it. Although this is effective, it is hardly efficient, humanitarian, viable, or desirable.

The C++ assert() function is similar; Whereas the Java assert() (which is new) throws an exception, C++'s eventually causes the program to exit (unless you have signal handling, but that's another story all together). This sudden exit can cause side-effects such as data-lost, because you may have not saved your data prior to finding this feature, but the example that always got me was when a friend of mine pointed out that if you have a train that is going fast, you might want to bring it to a stop before you exit your application.

Throwing an exception allows you to do this. In The C++ Programming Language, Bjarne Stroustrup first discusses assertions in terms of a logical criteria that must hold, such as is the case with preconditions and postconditions (Design by Contract anyone?). He goes on to say how assert() is enabled and disabled by the NDEBUG define so its not always there (not to fail to mention the assert()'s that have side-effects), and that calling abort() in production code is not usually acceptable. Interestingly enough, he suggests an alternative. It is a template named Assert(), which is not part of the C++ Standard Library, but the template takes a class as an exception and a class that overloads the operator! (preferably boolean in nature). When the operator! is called on the parameter and returns true, the template throws the exception. He refines the idea by adding a parameter that can be set to enable this type of assertion in various modules of his application.

Because the code for the Assert is so simple, it is tempting to just write the code inline and be done, however, Stroustrup also recommends that Assert() at least makes the code's intent known; looking at an if statement with a condition does not necessarily imply an assertion.

Modern C++ Design also demonstrates a compile-time assertion mechanism, which stops the compilation when a condition is false. This is useful for cases where you need to ensure, for example, that two structures are the same size. This is also done via a template, and while the true branch is implemented, the false branch is not, which actually causes the compilation error. This is interesting because if it compiles, it works; there is no chance of the application exiting or crashing because of this assert().

No matter whether you intend to use the assert() that calls abort() or the Stroustrup's Assert(), the important thing is to ensure that you are not using it for error handling. If a function fails, assert() is not the answer, and this is especially true in libraries. Instead, you should display some type of error message that helps to user figure out what has gone wrong; if a file does not exist, for example, just say that with printf() if you have nothing else. Your users should not think they are walking through a minefield when using your code.

Filed In

Navigation

eyt*