This mini-package provides a header
ZMtools/assertN.h,
that defines macros such as
assert2(condition).
These behave like the assert macro but permit gradations of
activation so that some set of asserts can remain active while
others disappear for optimization purposes.
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.
These packages may be obtained from the following sources:
fsgi02.fnal.gov),
in directories rooted at
/afs/fnal.gov/files/reports/working-groups/fpcltf/.
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.
assert1.
If any of these are triggered, the behavior is the
same as when an assert is triggered.
sanityCheck(condition) is also provided; this is not
deactivated by NDEBUG.
A discussion of the reasoning behind this is available.
We also provide a way to have assertion-failures channeled through the ErrorLogger mechanism if that is in use. This lets such messages be routed to the designated destinations which the experiment will be accustomed to perusing.
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.
ELasserts have the same semantics as the graded asserts
discussed above.
ELassert is triggered, it routes to
errlog an error
message of severity ELabort, containing the text
and the file and line of the failed assertion.
ELassert
macros is controlled by the same defines
as would control the gradations of ordinary assertions and sanity checks.
ELassert
macros, in the case where they are not activated,
preprocess down to no code at all.
ELwarning.
assertN.h.
Then use the following macros with the same semantics as assert():
NDEBUG.
NOSANCHECK;
these can remain active even if NDEBUG is defined.
NDEBUG deactivates all the asserts
(but not sanityCheck).
NDEBUG1 deactivates
assert1,
assert2,
and assert3,
assert,
nor sanityCheck).
NDEBUG2 deactivates
assert2
and assert3.
NDEBUG3 deactivates only
assert3.
NOSANCHECK deactivates only
sanityCheck,
and is the only way to deactivate that.
#include "ZMtools/assertN.h"
int transform(int);
bool testIfValid(int);
int i = transform(0);
sanityCheck (testIfValid(i)); // Not time critical; leave active in most cases.
for (i = 0; i < 100; i++) {
int j = transform(i);
assert (testIfValid(j)); // Normally active; off if NDEBUG defined.
for (int k = 0; k < j; k++) {
int m = transform(k);
assert3 (testIfValid(m)); // Inactive if any NDEBUGn is defined.
// One can imagine an experiment normally
// defining NDEBUG3 for all but some special
// extra-debugging builds.
}
}
Note that unless coders start employing the new graded forms of assert, the granularity will of course remain either all asserts active, or none.
ELassert
will appear,
there must be an
ErrorLog variable named
errlog. Also, the file
ErrorLogger/ELassertN.h must be included.
Then the following macros may be used, with the same semantics as the corresponding graded asserts:
NDEBUG,
NDEBUG1,
NDEBUG2, or NDEBUG3.
NDEBUG,
NDEBUG1,
or NDEBUG2.
NDEBUG
or NDEBUG1.
NDEBUG.
NOSANCHECK.
#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.)
Assertions Issuing Warnings
There are alternative macros, corresponding to each of the above, which
differ only in that any error message issued will be assigned severity
ELwarning.
This can be used, for instance, if there is some difficult optimization
which would be appropriate to implement if some condition is not super-rare;
so you may wish to test for that condition during the first part of production
running, but not to abort the jobs where it is detected.
NDEBUG,
NDEBUG1,
NDEBUG2, or NDEBUG3.
NDEBUG,
NDEBUG1,
or NDEBUG2.
NDEBUG
or NDEBUG1.
NDEBUG.
NOSANCHECK.
![]()
Mark Fischler
Last modified: May 11, 2000.