|Table of Contents||ChiLib Library Documentation|
The error reporting classes derive from the base class Error.
Error(const char* filename, int lineno, const char expr = 0, const char msg = 0); void abort(); virtual void message(ostream& os) const;
Error objects are usually constructed by the ASSERT macros, which supply the file and line information.
The message operation sends an error message to a stream. It is redefined by those classes that have interesting details in their error report. For example, BoundsError reports on the legal bounds and the value of the offending index.
If your compiler supports exceptions, the assert macros throw the error object. You should have main catch every object derived from Error, then inspect the call stack to see who threw it.
If your compiler does not support exceptions, the assert macros call abort on the error object. The abort operation prints a diagnostic message to cerr and terminates. Set a breakpoint here and then inspect the stack to find out who caused the error, or call message to get an error diagnostic.
PrecondError PostcondError InvariantError BoundsError MemError
are derived from Error. You can derive your own classes from Error.
We supply the following macros to generate error reporting.
ASSERT(expr); ASSERT_PRECOND(expr); ASSERT_POSTCOND(expr); ASSERT_INVARIANT(expr); ASSERT_MEM(pointer); ASSERT_BOUNDS(i, low, high);
The first four macros test the expression and report the error, with varying error messages.
The ASSERT_MEM argument tests the pointer, which presumably was returned from new, and tests whether it is non-null. This macro is not useful for compilers with exceptions because new throws an xalloc exception when it runs out of memory.
The ASSERT_BOUNDS macro is used in the string and array classes. It is not likely to be useful elsewhere. It tests whether low <= i <= high.
If NDEBUG is defined during compilation, none of these macros generate code. In particular, you are still responsible for doing something sensible to return from the operation.