1 | // Copyright (C) 2022 The Qt Company Ltd. |
2 | // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only |
3 | |
4 | #include "qssgassert_p.h" |
5 | |
6 | QT_BEGIN_NAMESPACE |
7 | |
8 | /*! |
9 | Collection of assert checks that causes a soft or hard assert depending on the build. Unlike Q_ASSERT(), |
10 | which is a no-op for non-debug build, QSSG_ASSERT() etc., will print a warning in non-developer builds (soft assert) |
11 | or terminate on developer-build (hard assert). |
12 | |
13 | \macro QSSG_ASSERT(condition, action) |
14 | \internal |
15 | |
16 | The assert will be fatal in developer builds if \a condition is not met. In non-developer builds |
17 | the assert is "soft" and will instead print a warning with the reason and location of the assert |
18 | before execution \a action. The \a action can be for example be: \c return, \c break or \c continue. |
19 | |
20 | For example, writing: |
21 | |
22 | \badcode |
23 | QSSG_ASSERT(ptr != nullptr, return); |
24 | \endcode |
25 | |
26 | other actions are of course possible, e.g., in a loop it might be better to do: |
27 | |
28 | \badcode |
29 | QSSG_ASSERT(ptr != nullptr, continue); |
30 | \endcode |
31 | |
32 | is the equivalent to: |
33 | |
34 | \badcode |
35 | Q_ASSERT(ptr != nullptr); |
36 | if (ptr != nullptr) { |
37 | qWarning() << "Something unexpected here, proceeding will be fatal!"; |
38 | return; |
39 | } |
40 | \endcode |
41 | |
42 | \sa QSSG_ASSERT_X |
43 | */ |
44 | |
45 | /*! |
46 | \macro QSSG_ASSERT_X(condition, message, action) |
47 | \internal |
48 | |
49 | Same as \l QSSG_ASSERT() but with a custom \a message that will be print if \a condition is not met. |
50 | */ |
51 | |
52 | /*! |
53 | \macro QSSG_CHECK(condition) |
54 | \internal |
55 | |
56 | Similar to \l QSSG_ASSERT but without an action. Convenient when the \a condition is expected to be valid, |
57 | but it's not immediately fatal if the current code path continues. |
58 | |
59 | \badcode |
60 | QSSG_CHECK(ptr != nullptr); |
61 | \endcode |
62 | |
63 | is the equivalent to: |
64 | |
65 | \badcode |
66 | Q_ASSERT(ptr != nullptr); |
67 | if (ptr != nullptr) |
68 | qWarning() << "Something unexpected here, will probably not work as expected!"; |
69 | \endcode |
70 | |
71 | \sa QSSG_CHECK_X |
72 | */ |
73 | |
74 | /*! |
75 | \macro QSSG_CHECK_X(condition, message) |
76 | \internal |
77 | |
78 | Same as \l QSSG_CHECK() but with a custom \a message that will be print if \a condition is not met. |
79 | */ |
80 | |
81 | /*! |
82 | \macro QSSG_GUARD(condition) |
83 | \internal |
84 | |
85 | Check that returns the result of \a condition. As with the other assert functions, a call to QSSG_GUARD, when \a condition |
86 | is not met, is fatal for developer builds. |
87 | |
88 | \badcode |
89 | |
90 | if (QSSG_GUARD(ptr != nullptr)) { |
91 | ... // OK |
92 | } else { |
93 | ... // We shouldn't be here! |
94 | } |
95 | |
96 | \endcode |
97 | |
98 | is the equivalent to: |
99 | |
100 | \badcode |
101 | if (ptr != nullptr) { |
102 | ... // OK |
103 | } else { |
104 | Q_ASSERT(ptr != nullptr); |
105 | qWarning() << "Something unexpected here!"; |
106 | } |
107 | \endcode |
108 | |
109 | \sa QSSG_GUARD_X |
110 | */ |
111 | |
112 | /*! |
113 | \macro QSSG_GUARD_X(condition, message) |
114 | \internal |
115 | |
116 | Same as \l QSSG_GUARD() but with a custom \a message that will be print if \a condition is not met. |
117 | */ |
118 | |
119 | /*! |
120 | \macro QSSG_DEBUG_COND(condition) |
121 | \internal |
122 | |
123 | Macro for condition that should only be run in debug builds. In releases build the macro |
124 | produces an "almost-no-op" condition (always true) and the \a condition is never run. |
125 | Can e.g., be combined with the assert checks to add potentially expensive sanity checks |
126 | that should only be run in debug builds. |
127 | |
128 | \badcode |
129 | QSSG_CEHCK(QSSG_DEBUG_COND(!list.contains(...))); |
130 | \endcode |
131 | |
132 | In a release build the \c QSSG_DEBUG_COND will never return \c false and the \a condition will never |
133 | be evaluated. |
134 | |
135 | \note DO NOT make surrounding code depend on the \a condition being evaluated or called!. |
136 | |
137 | \note Unlike the assert checks, this macro does not change behavior in relation to developer-builds. |
138 | */ |
139 | |
140 | void qssgWriteAssertLocation(const char *msg) |
141 | { |
142 | #if defined(QT_BUILD_INTERNAL) |
143 | qFatal(msg: "ASSERT: %s" , msg); |
144 | #else |
145 | qWarning("Unexpected condition met: %s" , msg); |
146 | #endif |
147 | } |
148 | |
149 | QT_END_NAMESPACE |
150 | |