The ErrorLogger package provides a header
ErrorLogger/ELassertN.h,
that defines macros such as
ELassert3(condition) and
ELwarningAssert2(condition).
These behave like the assert macro but permit gradations of
activation, and also route the output (when triggered) to
errlog, either with
severity ELabort or severity ELwarning.
The granularity of the C assert mechanism is inadequate for some purposes.
Every assert() macro is active unless NDEBUG
is not defined, and disappears if NDEBUG is defined.
For some assertions this is appropriate.
However, the coder may well know that some specific assertions are unlikely
to become time critical, and ought to remain active even though some degree
of optimization has been specified.
The mechanism we use to address this obeys the following rules:
NDEBUG, continues
to behave as in the standard manner, except for a different mode
of aborting when an ELassert assertion fails.
errlog,
of severity ELabort,
containing the text of the assertion
and the file and line of the failed assertion.
ELassert1.
If any of these are triggered, the behavior is the
same as when an ELassert is triggered.
ELassert1 is
de-activated if NDEBUG, NDEBUG1,
or NDEBUG2 is defined.
ELsanityCheck(condition) is also provided;
this is not
deactivated by NDEBUG.
A discussion of the reasoning behind this is available.
There is also a mechanism for declaring assertions that only generate
warnings if triggered, allowing a framework wants to continue processing
in some manner despite a failed (user) assertion. These are analogous to
the corresponding ELasserts but with names like
ELwarningAssert1.
ELassert
will appear,
there must be an
ErrorLog variable named
errlog. Also, the file
ErrorLogger/ELassertN.h must be included.
Having included ErrorLogger/ELassertN.h, one can use the
following macros with the same semantics as assert():
NDEBUG (only
triggering an ELabort severity mesasage to errlog when the assert fails).
NOSANCHECK;
these can remain active even if NDEBUG is defined.
The macros are controlled by symbols as follows:
NDEBUG,
NDEBUG1,
NDEBUG2, or NDEBUG3.
NDEBUG,
NDEBUG1,
or NDEBUG2.
NDEBUG
or NDEBUG1.
NDEBUG.
NOSANCHECK.
ErrorLogger/ELassertN.h may be included multiple times in the same
code unit.
Just like assert.h, it is not code-guarded; thus one can alter
the defined-status of the various NDEBUG symbols to modify the
activation status of ELassert statements in a given section of code.
An example code snippet:
#include "ErrorLogger/ELassertN.h"
int transform(int);
bool testIfValid(int);
int i = transform(0);
ELsanityCheck (testIfValid(i)); // Not time critical
for (i = 0; i < 100; i++) {
int j = transform(i);
ELassert (testIfValid(j)); // Normally active; off if NDEBUG is defined
for (int k = 0; k < j; k++) {
int m = transform(k);
ELassert3 (testIfValid(m)); // Inactive when any NDEBUGn is defined
}
}
If one of these macros is triggered, an error message is issued, with severity
ELabort.
This recommends that the program exit after outputting the error
information.
(The framework may be set up so as to ignore that recommendation.)
ELwarning.
NDEBUG,
NDEBUG1,
NDEBUG2, or NDEBUG3.
NDEBUG,
NDEBUG1,
or NDEBUG2.
NDEBUG
or NDEBUG1.
NDEBUG.
NOSANCHECK.