Drake
Drake C++ Documentation
Loading...
Searching...
No Matches
drake_assert.h File Reference

Detailed Description

Provides Drake's assertion mechanics.

They come in two flavors:

  • Double checking developer assumptions
    • DRAKE_ASSERT can be armed or disarmed independently from the system-wide asserts.
    • DRAKE_DEMAND is similar to DRAKE_ASSERT but is always armed.
  • Testing user inputs
    • DRAKE_THROW_UNLESS is similar to DRAKE_DEMAND, but uses exceptions instead of ::abort(). These are intended to be used both within Drake and by other software.
#include <array>
#include <string>
#include <tuple>
#include <type_traits>
#include <utility>
Include dependency graph for drake_assert.h:

Macros

#define DRAKE_ASSERT(condition)
 DRAKE_ASSERT(condition) is similar to the built-in assert(condition) from the C++ system header <cassert>.
#define DRAKE_ASSERT_VOID(expression)
 Like DRAKE_ASSERT, except that the expression must be void-valued; this allows for guarding expensive assertion-checking subroutines using the same macros as stand-alone assertions.
#define DRAKE_DEMAND(condition)
 Evaluates condition and iff the value is false will trigger an assertion failure with a message showing at least the condition text, function name, file, and line.
#define DRAKE_UNREACHABLE()
 Silences a "no return value" compiler warning by calling a function that always raises an exception or aborts (i.e., a function marked noreturn).
#define DRAKE_THROW_UNLESS(condition, ...)
 Provides a convenient wrapper to throw an exception when a condition is unmet.
#define DRAKE_DEREF(ptr)
 Derferences a pointer, with null checking.

Macro Definition Documentation

◆ DRAKE_ASSERT

#define DRAKE_ASSERT ( condition)

DRAKE_ASSERT(condition) is similar to the built-in assert(condition) from the C++ system header <cassert>.

Unless Drake's assertions are disarmed by the pre-processor definitions listed below, DRAKE_ASSERT will evaluate condition and iff the value is false will trigger an assertion failure with a message showing at least the condition text, function name, file, and line.

By default, assertion failures will :abort() the program. However, when using the pydrake python bindings, assertion failures will instead throw a C++ exception that causes a python SystemExit exception.

Assertions are enabled or disabled using the following pre-processor macros:

  • If DRAKE_ENABLE_ASSERTS is defined, then DRAKE_ASSERT is armed.
  • If DRAKE_DISABLE_ASSERTS is defined, then DRAKE_ASSERT is disarmed.
  • If both macros are defined, then it is a compile-time error.
  • If neither are defined, then NDEBUG governs assertions as usual.

This header will define exactly one of either DRAKE_ASSERT_IS_ARMED or DRAKE_ASSERT_IS_DISARMED to indicate whether DRAKE_ASSERT is armed.

This header will define both constexpr bool drake::kDrakeAssertIsArmed and constexpr bool drake::kDrakeAssertIsDisarmed globals.

One difference versus the standard assert(condition) is that the condition within DRAKE_ASSERT is always syntax-checked, even if Drake's assertions are disarmed.

Treat DRAKE_ASSERT like a statement – it must always be used in block scope, and must always be followed by a semicolon.

◆ DRAKE_ASSERT_VOID

#define DRAKE_ASSERT_VOID ( expression)

Like DRAKE_ASSERT, except that the expression must be void-valued; this allows for guarding expensive assertion-checking subroutines using the same macros as stand-alone assertions.

◆ DRAKE_DEMAND

#define DRAKE_DEMAND ( condition)

Evaluates condition and iff the value is false will trigger an assertion failure with a message showing at least the condition text, function name, file, and line.

◆ DRAKE_DEREF

#define DRAKE_DEREF ( ptr)

Derferences a pointer, with null checking.

If the provided pointer is null, throws an exception. Otherwise, returns a reference to the object being pointed to.

If the pointer points to a const type, a const reference is returned. If it points to a non-const type, a non-const reference is returned.

It will typically appear in a class's constructor when it aliases a an input parameter.

Example usage:

class Foo {
public:
Foo(const Bar* bar) : bar_(DRAKE_DEREF(bar)) {}
private:
const Bar& bar_;
};
@warning The pointer passed must be an l-value; do not pass in temporaries.
E.g., this includes function calls that return pointers and pointers to
arrays (&x[0]).
#define DRAKE_DEREF(ptr)
Derferences a pointer, with null checking.
Definition drake_assert.h:131
x
Definition light_parameter.h:147

◆ DRAKE_THROW_UNLESS

#define DRAKE_THROW_UNLESS ( condition,
... )

Provides a convenient wrapper to throw an exception when a condition is unmet.

This is similar to an assertion, but uses exceptions instead of ::abort(), and cannot be disabled.

Evaluates condition and iff the value is false will throw an exception with a message showing at least the condition text, function name, file, and line.

The condition must not be a pointer, where we'd implicitly rely on its nullness. Instead, always write out "!= nullptr" to be precise.

Correct: DRAKE_THROW_UNLESS(foo != nullptr); Incorrect: DRAKE_THROW_UNLESS(foo);

Because this macro is intended to provide a useful exception message to users, we should err on the side of extra detail about the failure. The meaning of "foo" isolated within error message text does not make it clear that a null pointer is the proximate cause of the problem.

In addition to the condition, up to four value expressions can be provided. Each value expression and its value will be included in the error message. For example:

DRAKE_THROW_UNLESS(x < 0, x);

Will include the the value of x in the message. If too many value expressions are specified, this will most likely produce a compiler error referencing "ENCODE_EACH".

Not all value expression types are supported. This shouldn't be interpreted as the definitive list. If yours isn't supported, feel free to submit a PR to add it (reaching out for help as appropriate).

◆ DRAKE_UNREACHABLE

#define DRAKE_UNREACHABLE ( )

Silences a "no return value" compiler warning by calling a function that always raises an exception or aborts (i.e., a function marked noreturn).

Only use this macro at a point where (1) a point in the code is truly unreachable, (2) the fact that it's unreachable is knowable from only reading the function itself (and not, e.g., some larger design invariant), and (3) there is a compiler warning if this macro were removed. The most common valid use is with a switch-case-return block where all cases are accounted for but the enclosing function is supposed to return a value. Do not use this macro as a "logic error" assertion; it should only be used to silence false positive warnings. When in doubt, throw an exception manually instead of using this macro.