QP/C  7.2.2
Real-Time Embedded Framework
Loading...
Searching...
No Matches
qassert.h
Go to the documentation of this file.
1/*$file${include::qassert.h} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/
2/*
3* Model: qpc.qm
4* File: ${include::qassert.h}
5*
6* This code has been generated by QM 5.2.5 <www.state-machine.com/qm>.
7* DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost.
8*
9* This code is covered by the following QP license:
10* License # : LicenseRef-QL-dual
11* Issued to : Any user of the QP/C real-time embedded framework
12* Framework(s) : qpc
13* Support ends : 2023-12-31
14* License scope:
15*
16* Copyright (C) 2005 Quantum Leaps, LLC <state-machine.com>.
17*
18* SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial
19*
20* This software is dual-licensed under the terms of the open source GNU
21* General Public License version 3 (or any later version), or alternatively,
22* under the terms of one of the closed source Quantum Leaps commercial
23* licenses.
24*
25* The terms of the open source GNU General Public License version 3
26* can be found at: <www.gnu.org/licenses/gpl-3.0>
27*
28* The terms of the closed source Quantum Leaps commercial licenses
29* can be found at: <www.state-machine.com/licensing>
30*
31* Redistributions in source code must retain this top-level comment block.
32* Plagiarizing this software to sidestep the license obligations is illegal.
33*
34* Contact information:
35* <www.state-machine.com/licensing>
36* <info@state-machine.com>
37*/
38/*$endhead${include::qassert.h} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/
39/*! @file
40* @brief Customizable and memory-efficient Design by Contract (DbC)
41* for embedded systems
42*
43* @note
44* This header file can be used in C, C++, and mixed C/C++ programs.
45*
46* @note
47* The preprocessor switch #QP_NSSM disables the QP Software Self-
48* Monitoring (SSM). However, it is generally **not** advisable to disable
49* SSM **especially** in the production code. Instead, the assertion
50* handler Q_onAssert() should be very carefully designed and tested.
51*/
52#ifndef QASSERT_H_
53#define QASSERT_H_
54
55#ifdef __cplusplus
56 extern "C" {
57#endif
58
59#ifndef QP_NSSM
60/*$declare${DbC::active} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/
61
62/*${DbC::active::Q_DEFINE_THIS_MODULE} .....................................*/
63/*! Define the user-specified module name for assertions in this file.
64*
65* @details
66* Macro to be placed at the top of each C/C++ module to define the
67* single instance of the module name string to be used in reporting
68* assertions in this module. This macro takes the user-supplied parameter
69* `name_` instead of `__FILE__` to precisely control the name of the
70* module.
71*
72* @param[in] name_ string constant representing the module name
73*
74* @note
75* This macro should **not** be terminated by a semicolon.
76*
77* @trace
78* - @tr{DVP-QP-PCLP-823}
79*/
80#define Q_DEFINE_THIS_MODULE(name_) \
81 static char const Q_this_module_[] = name_;
82
83/*${DbC::active::Q_ASSERT_ID} ..............................................*/
84/*! General-purpose assertion with user-specified ID number.
85*
86* @details
87* Evaluates the Boolean expression `expr_` and does nothing else when
88* it evaluates to 'true'. However, when `expr_` evaluates to 'false',
89* the Q_ASSERT_ID() macro calls the no-return function Q_onAssert().
90*
91* @param[in] id_ ID number (unique within the module) of the assertion
92* @param[in] expr_ Boolean expression to check
93*
94* @attention
95* When QP Software Self-Monitoring (SSM) is disabled (by defining
96* the macro #QP_NSSM), the Q_ASSERT_ID() macro expands to nothing, and
97* consequently the Boolean expression `expr_` is **not** evaluated and
98* the callback function Q_onAssert() is **not** called.
99*
100* @trace
101* - @tr{DVP-QP-MC3-D04_09A} (false-positive)
102*/
103#define Q_ASSERT_ID(id_, expr_) ((expr_) \
104 ? ((void)0) : Q_onAssert(&Q_this_module_[0], (id_)))
105
106/*${DbC::active::Q_ERROR_ID} ...............................................*/
107/*! Assertion with user-specified ID for a wrong path through the code
108*
109* @details
110* Calls the Q_onAssert() callback if ever executed. This assertion
111* takes the user-supplied parameter `id_` to identify the location of
112* this assertion within the file. This avoids the volatility of using
113* line numbers, which change whenever a line of code is added or removed
114* upstream from the assertion.
115*
116* @param[in] id_ ID number (unique within the module) of the assertion
117*
118* @note
119* Does noting when QP Software Self-Monitoring (SSM) is disabled
120* (by defining the macro #QP_NSSM).
121*
122* @trace
123* - @tr{DVP-QP-MC3-D04_09A} (false-positive)
124*/
125#define Q_ERROR_ID(id_) Q_onAssert(&Q_this_module_[0], (id_))
126
127/*${DbC::active::Q_ALLEGE_ID} ..............................................*/
128/*! General purpose assertion with user-specified ID number that
129* **always** evaluates the `expr_` expression.
130*
131* @details
132* Like the Q_ASSERT_ID() macro, except it **always** evaluates the
133* `expr_` expression even when assertions are disabled with the
134* #QP_NSSM macro. However, when the #QP_NSSM macro is defined, the
135* Q_onAssert() callback is **not** called, even if `expr_` evaluates
136* to FALSE.
137*
138* @param[in] id_ ID number (unique within the module) of the assertion
139* @param[in] expr_ Boolean expression to check
140*
141* @trace
142* - @tr{DVP-QP-MC3-D04_09A} (false-positive)
143*/
144#define Q_ALLEGE_ID(id_, expr_) Q_ASSERT_ID((id_), (expr_))
145/*$enddecl${DbC::active} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/
146#else
147/*$declare${DbC::inactive} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/
148
149/*${DbC::inactive::Q_DEFINE_THIS_MODULE} ...................................*/
150/*! inactive version of Q_DEFINE_THIS_MODULE() */
151#define Q_DEFINE_THIS_MODULE(name_)
152
153/*${DbC::inactive::Q_ASSERT_ID} ............................................*/
154/*! inactive version of Q_ASSERT_ID() */
155#define Q_ASSERT_ID(id_, expr_) ((void)0)
156
157/*${DbC::inactive::Q_ERROR_ID} .............................................*/
158/*! inactive version of Q_ERROR_ID() */
159#define Q_ERROR_ID(id_) ((void)0)
160
161/*${DbC::inactive::Q_ALLEGE_ID} ............................................*/
162/*! inactive version of Q_ALLEGE_ID()
163*
164* @attention
165* The expression `expr_` **is** evaluated, even though assertion
166* callback Q_onAssert() is NOT called when `expr_` evaluates to
167* false.
168*/
169#define Q_ALLEGE_ID(id_, expr_) ((void)(expr_))
170/*$enddecl${DbC::inactive} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/
171#endif
172
173/*$declare1${DbC} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/
174
175/*${DbC::Q_DEFINE_THIS_FILE} ...............................................*/
176/*! Define the file name (with `__FILE__`) for assertions in this file
177*
178* @details
179* Macro to be placed at the top of each C/C++ module to define the
180* single instance of the file name string to be used in reporting
181* assertions in this module.
182*
183* @note
184* The file name string literal is defined by means of the standard
185* preprocessor macro `__FILE__`. However, please note that, depending
186* on the compiler, the `__FILE__` macro might contain the whole path name
187* to the file, which might be inconvenient to log assertions.
188*
189* @attention
190* This macro should **not** be terminated by a semicolon.
191*
192* @trace
193* - @tr{DVP-QP-PCLP-823}
194* - @tr{DVP-QP-MC3-D04_09A} (false-positive)
195*/
196#define Q_DEFINE_THIS_FILE Q_DEFINE_THIS_MODULE(__FILE__)
197
198/*${DbC::Q_ASSERT} .........................................................*/
199/*! General-purpose assertion (with __LINE__ used as location in the file)
200*
201* @details
202* Equivalent to Q_ASSERT_ID(), except it uses __LINE__ to identify the
203* assertion within a file.
204*
205* @param[in] expr_ Boolean expression to check
206*
207* @trace
208* - @tr{DVP-QP-MC3-D04_09A} (false-positive)
209*/
210#define Q_ASSERT(expr_) Q_ASSERT_ID(__LINE__, (expr_))
211
212/*${DbC::Q_ERROR} ..........................................................*/
213/*! Assertion for a wrong path through the code
214*
215* @details
216* Calls the Q_onAssert() callback if ever executed.
217*
218* @note
219* This macro identifies the problem location with the line number,
220* which might change as the code is modified.
221*
222* @trace
223* - @tr{DVP-QP-MC3-D04_09A} (false-positive)
224*/
225#define Q_ERROR() Q_ERROR_ID(__LINE__)
226
227/*${DbC::Q_REQUIRE_ID} .....................................................*/
228/*! Assertion for checking **preconditions**.
229*
230* @details
231* Equivalent to Q_ASSERT_ID(), except the name provides a better
232* documentation of the intention of this assertion.
233*
234* @param[in] id_ ID number (unique within the module) of the assertion
235* @param[in] expr_ Boolean expression
236*
237* @trace
238* - @tr{DVP-QP-MC3-D04_09A} (false-positive)
239*/
240#define Q_REQUIRE_ID(id_, expr_) Q_ASSERT_ID((id_), (expr_))
241
242/*${DbC::Q_REQUIRE} ........................................................*/
243/*! Assertion for checking preconditions (based on __LINE__).
244*
245* @details
246* Equivalent to Q_ASSERT(), except the name provides a better documentation
247* of the intention of this assertion.
248*
249* @param[in] expr_ Boolean expression
250*
251* @trace
252* - @tr{DVP-QP-MC3-D04_09A} (false-positive)
253*/
254#define Q_REQUIRE(expr_) Q_ASSERT(expr_)
255
256/*${DbC::Q_ENSURE_ID} ......................................................*/
257/*! Assertion for checking postconditions.
258*
259* @details
260* Equivalent to Q_ASSERT_ID(), except the name provides a better documentation
261* of the intention of this assertion.
262*
263* @param[in] id_ ID number (unique within the module) of the assertion
264* @param[in] expr_ Boolean expression
265*/
266#define Q_ENSURE_ID(id_, expr_) Q_ASSERT_ID((id_), (expr_))
267
268/*${DbC::Q_ENSURE} .........................................................*/
269/*! Assertion for checking postconditions.
270*
271* @details
272* Equivalent to Q_ASSERT(), except the name provides a better documentation
273* of the intention of this assertion.
274*
275* @param[in] expr_ Boolean expression
276*
277* @trace
278* - @tr{DVP-QP-MC3-D04_09A} (false-positive)
279*/
280#define Q_ENSURE(expr_) Q_ASSERT(expr_)
281
282/*${DbC::Q_INVARIANT_ID} ...................................................*/
283/*! Assertion for checking invariants.
284*
285* @details
286* Equivalent to Q_ASSERT_ID(), except the name provides a better
287* documentation of the intention of this assertion.
288*
289* @param[in] id_ ID number (unique within the module) of the assertion
290* @param[in] expr_ Boolean expression
291*
292* @trace
293* - @tr{DVP-QP-MC3-D04_09A} (false-positive)
294*/
295#define Q_INVARIANT_ID(id_, expr_) Q_ASSERT_ID((id_), (expr_))
296
297/*${DbC::Q_INVARIANT} ......................................................*/
298/*! Assertion for checking invariants.
299*
300* @details
301* Equivalent to Q_ASSERT(), except the name provides a better documentation
302* of the intention of this assertion.
303*
304* @param[in] expr_ Boolean expression
305*
306* @trace
307* - @tr{DVP-QP-MC3-D04_09A} (false-positive)
308*/
309#define Q_INVARIANT(expr_) Q_ASSERT(expr_)
310
311/*${DbC::Q_ALLEGE} .........................................................*/
312/*! General purpose assertion with user-specified ID number that
313* **always** evaluates the `expr_` expression.
314*
315* @details
316* Equivalent to Q_ALLEGE_ID(), except it identifies the problem location
317* with the line number `__LINE__`, which might change as the code is modified.
318*
319* @param[in] expr_ Boolean expression to check
320*
321* @trace
322* - @tr{DVP-QP-MC3-D04_09A} (false-positive)
323*/
324#define Q_ALLEGE(expr_) Q_ALLEGE_ID(__LINE__, (expr_))
325
326/*${DbC::Q_ASSERT_STATIC} ..................................................*/
327/*! Static (compile-time) assertion.
328*
329* @details
330* This type of assertion deliberately causes a compile-time error when
331* the `expr_` Boolean expression evaluates to FALSE. The macro exploits
332* the fact that in C/C++ a dimension of an array cannot be negative.
333* The compile-time assertion has no runtime side effects.
334*
335* @param[in] expr_ Compile-time Boolean expression
336*
337* @note
338* The static assertion macro is provided for backwards compatibility with
339* older C standards. Newer C11 supports `_Static_assert()`, which should
340* be used instead of Q_ASSERT_STATIC().
341*
342* @trace
343* - @tr{DVP-QP-MC3-D04_09A} (false-positive)
344*/
345#define Q_ASSERT_STATIC(expr_) extern char Q_static_assert_[(expr_) ? 1 : -1]
346
347/*${DbC::Q_NORETURN} .......................................................*/
348#ifndef Q_NORETURN
349/*! No-return function specifier for the Q_onAssert() callback function.
350*
351* @details
352* If the `Q_NORETURN` macro is undefined, the default definition uses
353* the C99 specifier `_Noreturn`.
354*
355* @note
356* The `Q_NORETURN` macro can be defined in the QP port (typically in
357* `qep_port.h` or `qep_port.hpp`). If such definition is porvided
358* the default won't be used.
359*
360* @trace
361* - @tr{DVP-QP-MC3-R01_04}
362*/
363#define Q_NORETURN _Noreturn void
364#endif /* ndef Q_NORETURN */
365
366/*${DbC::int_t} ............................................................*/
367#ifndef QP_VERSION
368/*! typedef for assertions-ids and line numbers in assertions.
369*
370* @details
371* This typedef specifies integer type for exclusive use in assertions.
372* Use of this type, rather than plain 'int', is in compliance
373* with the MISRA-C:2012 Directive 4.6 (Advisory).
374*/
375typedef int int_t;
376#endif /* ndef QP_VERSION */
377
378/*${DbC::Q_onAssert} .......................................................*/
379/*! Callback function invoked in case of an assertion failure.
380*
381* @details
382* This callback function needs to be defined in the application to perform
383* any corrective action after a non-recoverable error has been detected.
384* The Q_onAssert() function is the last line of defense after the
385* system failure and its implementation shouild be very **carefully**
386* designed and **tested** under various fault conditions, including but
387* not limited to: stack overflow, stack corruption, or calling Q_onAssert()
388* from an interrupt.
389*
390* @param[in] module name of the file/module in which the assertion failed
391* (constant, zero-terminated C string)
392* @param[in] location location of the assertion within the module. This could
393* be a line number or a user-specified ID-number.
394*
395* @returns
396* This callback function should **not return** (see ::Q_NORETURN),
397* as continuation after an assertion failure does not make sense.
398*
399* @note
400* During debugging, Q_onAssert() is an ideal place to put a breakpoint.
401* For deployment, tt is typically a **bad idea** to implement Q_onAssert()
402* as an endless loop that ties up the CPU (denial of service).
403*
404* Called by the following: Q_ASSERT_ID(), Q_ERROR_ID(), Q_REQUIRE_ID(),
405* Q_ENSURE_ID(), Q_INVARIANT_ID() and Q_ALLEGE_ID() as well as:
406* Q_ASSERT(), Q_ERROR(), Q_REQUIRE(), Q_ENSURE(), Q_INVARIANT(),
407* and Q_ALLEGE().
408*/
410 char const * module,
411 int_t location);
412
413/*${DbC::Q_DIM} ............................................................*/
414#ifndef QP_VERSION
415/*! Helper macro to calculate static dimension of a 1-dim `array_`
416*
417* @param array_ 1-dimensional array
418*
419* @returns
420* The length of the array (number of elements it can hold)
421*
422* @trace
423* - @tr{DVP-QP-MC3-D04_09A} (false-positive)
424*/
425#define Q_DIM(array_) (sizeof(array_) / sizeof((array_)[0U]))
426#endif /* ndef QP_VERSION */
427/*$enddecl${DbC} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/
428
429#ifdef __cplusplus
430 }
431#endif
432
433#endif /* QASSERT_H_ */
#define Q_NORETURN
Definition: qassert.h:363
Q_NORETURN Q_onAssert(char const *module, int_t location)
Definition: qutest.c:112
int int_t
Definition: qassert.h:375