Typedefs | Functions | Variables
Sawyer::Assert Namespace Reference


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":

Some examples:

// Require the condition to be true, or fail with this message.
ASSERT_require2(sz1 > sz2, "vector one must have more elements than vector two");
// Forbid a vector from being empty.
ASSERT_forbid2(users.empty(), "search must have yielded at least one user");
// Plain, old-fashioned assert.
ASSERT_require(pointer != NULL)
// A better way to write the same thing.
// An even better way to write the same thing.
ASSERT_not_null2(pointer, "foo has failed to obtain a valid bar");

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.

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:

int main(int argc, char *argv[]) {
Sawyer::Message::assertionStream = Sawer::Message::mlog[FATAL];


typedef void(* AssertFailureHandler) (const char *mesg, const char *expr, const std::string &note, const char *filename, unsigned linenum, const char *funcname)
 Type for user-defined assertion failure handler. More...


void fail (const char *mesg, const char *expr, const std::string &note, const char *filename, unsigned linenum, const char *funcname)
 Cause immediate failure. More...


AssertFailureHandler assertFailureHandler
 Optional user callback to handle assertion failures. More...

Typedef Documentation

typedef void(* Sawyer::Assert::AssertFailureHandler) (const char *mesg, const char *expr, const std::string &note, const char *filename, unsigned linenum, const char *funcname)

Type for user-defined assertion failure handler.

Definition at line 108 of file Assert.h.

Function Documentation

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.

Variable Documentation

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.