ROSE
0.11.96.11
|
Run-time logic assertions.
This library defines a collection of logic assertion macros (mostly) beginning with "ASSERT_". Many of the macros come in two flavors: with or without an std::string
argument to describe what is being asserted. Since there is not an official portable way for macros to have a variable number of arguments, macros that take a descriptive string have "2" appended to their names. Macros with "always" in their name are always enabled, while some of the others are only enabled when NDEBUG
and SAWYER_NDEBUG
are both undefined. Macros that are enabled evaluate their arguments one time each, and macros that are disabled do not evaluate their arguments at all.
The following macros are defined with "ASSERT_" prefix, optional "always", and optional trailing "2":
require(expr, [note])
: Asserts that expr evaluates to true, or fails with the message "assertion failed: required" with details about the failure. forbid(expr, [note])
: Asserts that expr evaluates to false, or fails with the message "assertion failed: prohibitted" with details about the failure. not_null(expr, [note])
: Asserts that expr evaluate to non-null, or fails with the message "null pointer" with details about the failure. this()
: Asserts that the containing function is an object method invoked on a non-null object. If the function is not an object method then the compiler will emit an error. If the object is null at the time of invocation then the program fails with the message "'this' cannot be null in an object method". not_reachable(note)
: Always fails with the message "reached impossible state". This macro is not disabled when SAWYER_NDEBUG is set. not_implemented(note)
: Always fails with the message "not implemented yet". This macro is not disabled when SAWYER_NDEBUG is set.Some examples:
The following macros do not start with "ASSERT_" because they are widely recognized by IDEs. They are aso not disabled when SAWYER_NDEBUG
is set.
TODO(note)
: Always fails with the message "not implemented yet". FIXME(note)
: Always fails with the message "needs to be fixed". When using a note argument, the note should be written in the affirmative, i.e., a statement of what condition causes the assertion to pass. It should describe what the macro is asserting, not what went wrong when the macro failed. For instance, if you're checking that two vectors are the same length, then the note should be something like "name and ID vectors must be the same size". Writing notes in the affirmative has two benefits: (1) the note documents the code, and (2) if the assertion fails the message makes sense to the user, namely "assertion failed: name and ID vectors must be the same size".
Failed assertions output to Sawyer::Message::assertionStream, which defaults to Sawyer::Message::mlog[FATAL]
. This variable is initialized at the first call to fail if it is a null pointer. Users can assign a different stream to it any time before then:
Typedefs | |
typedef void(* | AssertFailureHandler) (const char *mesg, const char *expr, const std::string ¬e, const char *filename, unsigned linenum, const char *funcname) |
Type for user-defined assertion failure handler. | |
Functions | |
void | fail (const char *mesg, const char *expr, const std::string ¬e, const char *filename, unsigned linenum, const char *funcname) |
Cause immediate failure. More... | |
Variables | |
AssertFailureHandler | assertFailureHandler |
Optional user callback to handle assertion failures. More... | |
void Sawyer::Assert::fail | ( | const char * | mesg, |
const char * | expr, | ||
const std::string & | note, | ||
const char * | filename, | ||
unsigned | linenum, | ||
const char * | funcname | ||
) |
Cause immediate failure.
This function is the low-level function called by most of the other Sawyer::Assert macros when an assertion fails. Calls to this function do not return.
AssertFailureHandler Sawyer::Assert::assertFailureHandler |
Optional user callback to handle assertion failures.
If this variable has a non-null value, then that function is called after the failed assertion message is emitted. This allows the user to terminate the program some other way than the default abort
call. In any case, this function should not return; if it does, then abort
is called.