Drake
drake_assert.h
Go to the documentation of this file.
1 #pragma once
2 
3 #include <type_traits>
4 
5 /// @file
6 /// Provides Drake's assertion implementation. This is intended to be used
7 /// both within Drake and by other software. Drake's asserts can be armed
8 /// and disarmed independently from the system-wide asserts.
9 
10 #ifdef DRAKE_DOXYGEN_CXX
11 /// @p DRAKE_ASSERT(condition) is similar to the built-in @p assert(condition)
12 /// from the C++ system header @p <cassert>. Unless Drake's assertions are
13 /// disarmed by the pre-processor definitions listed below, @p DRAKE_ASSERT
14 /// will evaluate @p condition and iff the value is false will trigger an
15 /// assertion failure with a message showing at least the condition text,
16 /// function name, file, and line.
17 ///
18 /// By default, assertion failures will :abort() the program. However, when
19 /// using the pydrake python bindings, assertion failures will instead throw a
20 /// C++ exception that causes a python SystemExit exception.
21 ///
22 /// Assertions are enabled or disabled using the following pre-processor macros:
23 /// - If @p DRAKE_ENABLE_ASSERTS is defined, then @p DRAKE_ASSERT is armed.
24 /// - If @p DRAKE_DISABLE_ASSERTS is defined, then @p DRAKE_ASSERT is disarmed.
25 /// - If both macros are defined, then it is a compile-time error.
26 /// - If neither are defined, then NDEBUG governs assertions as usual.
27 ///
28 /// This header will define exactly one of either @p DRAKE_ASSERT_IS_ARMED or
29 /// @p DRAKE_ASSERT_IS_DISARMED to indicate whether @p DRAKE_ASSERT is armed.
30 ///
31 /// One difference versus the standard @p assert(condition) is that the
32 /// @p condition within @p DRAKE_ASSERT is always syntax-checked, even if
33 /// Drake's assertions are disarmed.
34 ///
35 /// Treat @p DRAKE_ASSERT like a statement -- it must always be used
36 /// in block scope, and must always be followed by a semicolon.
37 #define DRAKE_ASSERT(condition)
38 /// Like @p DRAKE_ASSERT, except that the expression must be void-valued; this
39 /// allows for guarding expensive assertion-checking subroutines using the same
40 /// macros as stand-alone assertions.
41 #define DRAKE_ASSERT_VOID(expression)
42 /// Evaluates @p condition and iff the value is false will trigger an assertion
43 /// failure with a message showing at least the condition text, function name,
44 /// file, and line.
45 #define DRAKE_DEMAND(condition)
46 /// Aborts the program (via ::abort) with a message showing at least the
47 /// function name, file, and line.
48 #define DRAKE_ABORT()
49 /// Aborts the program (via ::abort) with a message showing at least the
50 /// given message (macro argument), function name, file, and line.
51 #define DRAKE_ABORT_MSG(message)
52 #else // DRAKE_DOXYGEN_CXX
53 
54 // Users should NOT set these; only this header should set them.
55 #ifdef DRAKE_ASSERT_IS_ARMED
56 # error Unexpected DRAKE_ASSERT_IS_ARMED defined.
57 #endif
58 #ifdef DRAKE_ASSERT_IS_DISARMED
59 # error Unexpected DRAKE_ASSERT_IS_DISARMED defined.
60 #endif
61 
62 // Decide whether Drake assertions are enabled.
63 #if defined(DRAKE_ENABLE_ASSERTS) && defined(DRAKE_DISABLE_ASSERTS)
64 # error Conflicting assertion toggles.
65 #elif defined(DRAKE_ENABLE_ASSERTS)
66 # define DRAKE_ASSERT_IS_ARMED
67 #elif defined(DRAKE_DISABLE_ASSERTS) || defined(NDEBUG)
68 # define DRAKE_ASSERT_IS_DISARMED
69 #else
70 # define DRAKE_ASSERT_IS_ARMED
71 #endif
72 
73 namespace drake {
74 namespace detail {
75 // Abort the program with an error message.
76 __attribute__((noreturn)) /* gcc is ok with [[noreturn]]; clang is not. */
77 void Abort(const char* condition, const char* func, const char* file, int line);
78 // Report an assertion failure; will either Abort(...) or throw.
79 __attribute__((noreturn)) /* gcc is ok with [[noreturn]]; clang is not. */
80 void AssertionFailed(
81  const char* condition, const char* func, const char* file, int line);
82 } // namespace detail
83 namespace assert {
84 // Allows for specialization of how to bool-convert Conditions used in
85 // assertions, in case they are not intrinsically convertible. See
86 // symbolic_formula.h for an example use. This is a public interface to
87 // extend; it is intended to be specialized by unusual Scalar types that
88 // require special handling.
89 template <typename Condition>
90 struct ConditionTraits {
91  static constexpr bool is_valid = std::is_convertible<Condition, bool>::value;
92  static bool Evaluate(const Condition& value) {
93  return value;
94  }
95 };
96 } // namespace assert
97 } // namespace drake
98 
99 #define DRAKE_ABORT() \
100  ::drake::detail::Abort(nullptr, __func__, __FILE__, __LINE__)
101 
102 #define DRAKE_DEMAND(condition) \
103  do { \
104  typedef ::drake::assert::ConditionTraits< \
105  typename std::remove_cv<decltype(condition)>::type> Trait; \
106  static_assert(Trait::is_valid, "Condition should be bool-convertible."); \
107  if (!Trait::Evaluate(condition)) { \
108  ::drake::detail::AssertionFailed( \
109  #condition, __func__, __FILE__, __LINE__); \
110  } \
111  } while (0)
112 
113 #define DRAKE_ABORT_MSG(msg) \
114  ::drake::detail::Abort(msg, __func__, __FILE__, __LINE__)
115 
116 #ifdef DRAKE_ASSERT_IS_ARMED
117 // Assertions are enabled.
118 # define DRAKE_ASSERT(condition) DRAKE_DEMAND(condition)
119 # define DRAKE_ASSERT_VOID(expression) do { \
120  static_assert( \
121  std::is_convertible<decltype(expression), void>::value, \
122  "Expression should be void."); \
123  expression; \
124  } while (0)
125 #else
126 // Assertions are disabled, so just typecheck the expression.
127 # define DRAKE_ASSERT(condition) static_assert( \
128  ::drake::assert::ConditionTraits< \
129  typename std::remove_cv<decltype(condition)>::type>::is_valid, \
130  "Condition should be bool-convertible.");
131 # define DRAKE_ASSERT_VOID(expression) static_assert( \
132  std::is_convertible<decltype(expression), void>::value, \
133  "Expression should be void.")
134 #endif
135 
136 #endif // DRAKE_DOXYGEN_CXX
const char const char int line
Definition: drake_throw.h:16
Definition: automotive_demo.cc:88
void AssertionFailed(const char *condition, const char *func, const char *file, int line)
Definition: drake_assert_and_throw.cc:61
int value
Definition: copyable_unique_ptr_test.cc:61
__attribute__((noreturn)) void Throw(const char *condition
const char const char * file
Definition: drake_throw.h:16
void Abort(const char *condition, const char *func, const char *file, int line)
Definition: drake_assert_and_throw.cc:44
const char * func
Definition: drake_throw.h:16