2022-04-19 19:23:30 -04:00
|
|
|
/*============================================================================
|
|
|
|
* QP/C Real-Time Embedded Framework (RTEF)
|
|
|
|
* Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved.
|
2012-08-14 18:00:48 -04:00
|
|
|
*
|
2022-04-19 19:23:30 -04:00
|
|
|
* SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial
|
2012-08-14 18:00:48 -04:00
|
|
|
*
|
2022-04-19 19:23:30 -04:00
|
|
|
* This software is dual-licensed under the terms of the open source GNU
|
|
|
|
* General Public License version 3 (or any later version), or alternatively,
|
|
|
|
* under the terms of one of the closed source Quantum Leaps commercial
|
|
|
|
* licenses.
|
2012-08-14 18:00:48 -04:00
|
|
|
*
|
2022-04-19 19:23:30 -04:00
|
|
|
* The terms of the open source GNU General Public License version 3
|
|
|
|
* can be found at: <www.gnu.org/licenses/gpl-3.0>
|
2012-08-14 18:00:48 -04:00
|
|
|
*
|
2022-04-19 19:23:30 -04:00
|
|
|
* The terms of the closed source Quantum Leaps commercial licenses
|
|
|
|
* can be found at: <www.state-machine.com/licensing>
|
2012-08-14 18:00:48 -04:00
|
|
|
*
|
2022-04-19 19:23:30 -04:00
|
|
|
* Redistributions in source code must retain this top-level comment block.
|
|
|
|
* Plagiarizing this software to sidestep the license obligations is illegal.
|
2012-08-14 18:00:48 -04:00
|
|
|
*
|
|
|
|
* Contact information:
|
2022-04-19 19:23:30 -04:00
|
|
|
* <www.state-machine.com>
|
2019-10-27 12:26:31 -04:00
|
|
|
* <info@state-machine.com>
|
2022-04-19 19:23:30 -04:00
|
|
|
============================================================================*/
|
|
|
|
/*!
|
|
|
|
* @date Last updated on: 2021-12-23
|
|
|
|
* @version Last updated for: @ref qpc_7_0_0
|
|
|
|
*
|
|
|
|
* @file
|
|
|
|
* @brief Customizable and memory-efficient assertions for embedded systems
|
2014-04-13 21:35:34 -04:00
|
|
|
*/
|
2019-10-27 12:26:31 -04:00
|
|
|
#ifndef QASSERT_H
|
|
|
|
#define QASSERT_H
|
2012-08-14 18:00:48 -04:00
|
|
|
|
2022-04-19 19:23:30 -04:00
|
|
|
/*!
|
2015-05-14 16:05:04 -04:00
|
|
|
* @note
|
2014-04-13 21:35:34 -04:00
|
|
|
* This header file can be used in C, C++, and mixed C/C++ programs.
|
2012-08-14 18:00:48 -04:00
|
|
|
*
|
2022-04-19 19:23:30 -04:00
|
|
|
* @note
|
|
|
|
* The preprocessor switch #Q_NASSERT disables checking assertions.
|
2014-04-13 21:35:34 -04:00
|
|
|
* However, it is generally __not__ advisable to disable assertions,
|
|
|
|
* __especially__ in the production code. Instead, the assertion handler
|
|
|
|
* Q_onAssert() should be very carefully designed and tested.
|
2012-08-14 18:00:48 -04:00
|
|
|
*/
|
2014-04-13 21:35:34 -04:00
|
|
|
|
|
|
|
#ifdef Q_NASSERT /* Q_NASSERT defined--assertion checking disabled */
|
2012-08-14 18:00:48 -04:00
|
|
|
|
2018-04-20 16:16:53 -04:00
|
|
|
/* provide dummy (empty) definitions that don't generate any code... */
|
2012-08-14 18:00:48 -04:00
|
|
|
#define Q_DEFINE_THIS_FILE
|
|
|
|
#define Q_DEFINE_THIS_MODULE(name_)
|
|
|
|
#define Q_ASSERT(test_) ((void)0)
|
|
|
|
#define Q_ASSERT_ID(id_, test_) ((void)0)
|
|
|
|
#define Q_ALLEGE(test_) ((void)(test_))
|
|
|
|
#define Q_ALLEGE_ID(id_, test_) ((void)(test_))
|
|
|
|
#define Q_ERROR() ((void)0)
|
|
|
|
#define Q_ERROR_ID(id_) ((void)0)
|
|
|
|
|
2014-04-13 21:35:34 -04:00
|
|
|
#else /* Q_NASSERT not defined--assertion checking enabled */
|
2012-08-14 18:00:48 -04:00
|
|
|
|
2019-10-27 12:26:31 -04:00
|
|
|
#ifndef QP_VERSION /* is quassert.h used outside QP? */
|
2018-04-20 16:16:53 -04:00
|
|
|
|
|
|
|
/* provide typedefs so that qassert.h could be used "standalone"... */
|
|
|
|
|
2022-04-19 19:23:30 -04:00
|
|
|
/*! typedef for assertions-ids and line numbers in assertions.
|
2022-05-09 14:52:11 -04:00
|
|
|
* @details
|
2018-04-20 16:16:53 -04:00
|
|
|
* This typedef specifies integer type for exclusive use in assertions.
|
|
|
|
* Use of this type, rather than plain 'int', is in compliance
|
2022-04-19 19:23:30 -04:00
|
|
|
* with the MISRA-C 2012 Dir 4.6 (adv).
|
2018-04-20 16:16:53 -04:00
|
|
|
*/
|
|
|
|
typedef int int_t;
|
|
|
|
|
|
|
|
#endif
|
|
|
|
|
2022-04-19 19:23:30 -04:00
|
|
|
/*! Define the file name (with `__FILE__`) for assertions in this file
|
2022-05-09 14:52:11 -04:00
|
|
|
* @details
|
2014-04-13 21:35:34 -04:00
|
|
|
* Macro to be placed at the top of each C/C++ module to define the
|
|
|
|
* single instance of the file name string to be used in reporting
|
|
|
|
* assertions in this module.
|
|
|
|
*
|
2015-05-14 16:05:04 -04:00
|
|
|
* @note The file name string literal is defined by means of the standard
|
2014-04-13 21:35:34 -04:00
|
|
|
* preprocessor macro `__FILE__`. However, please note that, depending
|
|
|
|
* on the compiler, the `__FILE__` macro might contain the whole path name
|
|
|
|
* to the file, which might be inconvenient to log assertions.
|
2015-05-14 16:05:04 -04:00
|
|
|
* @note This macro should __not__ be terminated by a semicolon.
|
|
|
|
* @sa Q_DEFINE_THIS_MODULE()
|
2012-08-14 18:00:48 -04:00
|
|
|
*/
|
|
|
|
#define Q_DEFINE_THIS_FILE \
|
2022-04-19 19:23:30 -04:00
|
|
|
static char const Q_this_module_[] = __FILE__;
|
2012-08-14 18:00:48 -04:00
|
|
|
|
2022-04-19 19:23:30 -04:00
|
|
|
/*! Define the user-specified module name for assertions in this file.
|
2022-05-09 14:52:11 -04:00
|
|
|
* @details
|
2014-04-13 21:35:34 -04:00
|
|
|
* Macro to be placed at the top of each C/C++ module to define the
|
|
|
|
* single instance of the module name string to be used in reporting
|
2015-05-14 16:05:04 -04:00
|
|
|
* assertions in this module. This macro takes the user-supplied parameter
|
|
|
|
* @p name_ instead of `__FILE__` to precisely control the name of the
|
2014-04-13 21:35:34 -04:00
|
|
|
* module.
|
|
|
|
*
|
2015-05-14 16:05:04 -04:00
|
|
|
* @param[in] name_ string constant representing the module name
|
2014-04-13 21:35:34 -04:00
|
|
|
*
|
2015-05-14 16:05:04 -04:00
|
|
|
* @note This macro should __not__ be terminated by a semicolon.
|
2012-08-14 18:00:48 -04:00
|
|
|
*/
|
|
|
|
#define Q_DEFINE_THIS_MODULE(name_) \
|
2022-04-19 19:23:30 -04:00
|
|
|
static char const Q_this_module_[] = name_;
|
2012-08-14 18:00:48 -04:00
|
|
|
|
2022-04-19 19:23:30 -04:00
|
|
|
/*! General purpose assertion.
|
2022-05-09 14:52:11 -04:00
|
|
|
* @details
|
2015-05-14 16:05:04 -04:00
|
|
|
* Makes sure the @p test_ parameter is TRUE. Calls the Q_onAssert()
|
|
|
|
* callback if the @p test_ expression evaluates to FALSE. This
|
2014-04-13 21:35:34 -04:00
|
|
|
* macro identifies the assertion location within the file by means
|
|
|
|
* of the standard `__LINE__` macro.
|
|
|
|
*
|
2015-05-14 16:05:04 -04:00
|
|
|
* @param[in] test_ Boolean expression
|
2014-04-13 21:35:34 -04:00
|
|
|
*
|
2015-05-14 16:05:04 -04:00
|
|
|
* @note the @p test_ is __not__ evaluated if assertions are disabled
|
2014-04-13 21:35:34 -04:00
|
|
|
* with the #Q_NASSERT switch.
|
2012-08-14 18:00:48 -04:00
|
|
|
*/
|
2013-10-10 20:01:51 -04:00
|
|
|
#define Q_ASSERT(test_) ((test_) \
|
2020-03-17 21:33:58 -04:00
|
|
|
? (void)0 : Q_onAssert(&Q_this_module_[0], __LINE__))
|
2012-08-14 18:00:48 -04:00
|
|
|
|
2022-04-19 19:23:30 -04:00
|
|
|
/*! General purpose assertion with user-specified assertion-id.
|
2022-05-09 14:52:11 -04:00
|
|
|
* @details
|
2015-05-14 16:05:04 -04:00
|
|
|
* Makes sure the @p test_ parameter is TRUE. Calls the Q_onAssert()
|
|
|
|
* callback if the @p test_ evaluates to FALSE. This assertion takes the
|
|
|
|
* user-supplied parameter @p id_ to identify the location of this
|
2014-04-13 21:35:34 -04:00
|
|
|
* assertion within the file. This avoids the volatility of using line
|
|
|
|
* numbers, which change whenever a line of code is added or removed
|
|
|
|
* upstream from the assertion.
|
|
|
|
*
|
2015-05-14 16:05:04 -04:00
|
|
|
* @param[in] id_ ID number (unique within the module) of the assertion
|
|
|
|
* @param[in] test_ Boolean expression
|
2014-04-13 21:35:34 -04:00
|
|
|
*
|
2015-05-14 16:05:04 -04:00
|
|
|
* @note the @p test_ expression is __not__ evaluated if assertions are
|
2014-04-13 21:35:34 -04:00
|
|
|
* disabled with the #Q_NASSERT switch.
|
2012-08-14 18:00:48 -04:00
|
|
|
*/
|
2013-10-10 20:01:51 -04:00
|
|
|
#define Q_ASSERT_ID(id_, test_) ((test_) \
|
2020-03-17 21:33:58 -04:00
|
|
|
? (void)0 : Q_onAssert(&Q_this_module_[0], (id_)))
|
2014-04-13 21:35:34 -04:00
|
|
|
|
2015-05-14 16:05:04 -04:00
|
|
|
/*! General purpose assertion that __always__ evaluates the @p test_
|
2022-04-19 19:23:30 -04:00
|
|
|
* expression.
|
2022-05-09 14:52:11 -04:00
|
|
|
* @details
|
2015-05-14 16:05:04 -04:00
|
|
|
* Like the Q_ASSERT() macro, except it __always__ evaluates the @p test_
|
2014-04-13 21:35:34 -04:00
|
|
|
* expression even when assertions are disabled with the #Q_NASSERT macro.
|
|
|
|
* However, when the #Q_NASSERT macro is defined, the Q_onAssert()
|
2015-05-14 16:05:04 -04:00
|
|
|
* callback is __not__ called, even if @p test_ evaluates to FALSE.
|
2014-04-13 21:35:34 -04:00
|
|
|
*
|
2015-05-14 16:05:04 -04:00
|
|
|
* @param[in] test_ Boolean expression (__always__ evaluated)
|
2014-04-13 21:35:34 -04:00
|
|
|
*
|
2015-05-14 16:05:04 -04:00
|
|
|
* @sa #Q_ALLEGE_ID
|
2012-08-14 18:00:48 -04:00
|
|
|
*/
|
|
|
|
#define Q_ALLEGE(test_) Q_ASSERT(test_)
|
|
|
|
|
2014-04-13 21:35:34 -04:00
|
|
|
/*! General purpose assertion with user-specified assertion-id that
|
2022-04-19 19:23:30 -04:00
|
|
|
* __always__ evaluates the @p test_ expression.
|
2022-05-09 14:52:11 -04:00
|
|
|
* @details
|
2014-04-13 21:35:34 -04:00
|
|
|
* Like the Q_ASSERT_ID() macro, except it __always__ evaluates the
|
2015-05-14 16:05:04 -04:00
|
|
|
* @p test_ expression even when assertions are disabled with the
|
2014-04-13 21:35:34 -04:00
|
|
|
* #Q_NASSERT macro. However, when the #Q_NASSERT macro is defined, the
|
2015-05-14 16:05:04 -04:00
|
|
|
* Q_onAssert() callback is __not__ called, even if @p test_ evaluates
|
2014-04-13 21:35:34 -04:00
|
|
|
* to FALSE.
|
|
|
|
*
|
2015-05-14 16:05:04 -04:00
|
|
|
* @param[in] id_ ID number (unique within the module) of the assertion
|
|
|
|
* @param[in] test_ Boolean expression
|
2012-08-14 18:00:48 -04:00
|
|
|
*/
|
2015-05-14 16:05:04 -04:00
|
|
|
#define Q_ALLEGE_ID(id_, test_) Q_ASSERT_ID((id_), (test_))
|
2012-08-14 18:00:48 -04:00
|
|
|
|
2022-04-19 19:23:30 -04:00
|
|
|
/*! Assertion for a wrong path through the code.
|
2022-05-09 14:52:11 -04:00
|
|
|
* @details
|
2014-04-13 21:35:34 -04:00
|
|
|
* Calls the Q_onAssert() callback if ever executed.
|
|
|
|
*
|
2015-05-14 16:05:04 -04:00
|
|
|
* @note Does noting if assertions are disabled with the #Q_NASSERT switch.
|
2012-08-14 18:00:48 -04:00
|
|
|
*/
|
|
|
|
#define Q_ERROR() \
|
2020-03-17 21:33:58 -04:00
|
|
|
Q_onAssert(&Q_this_module_[0], __LINE__)
|
2012-08-14 18:00:48 -04:00
|
|
|
|
2022-04-19 19:23:30 -04:00
|
|
|
/*! Assertion with user-specified assertion-id for a wrong path
|
2022-05-09 14:52:11 -04:00
|
|
|
* @details
|
2014-04-13 21:35:34 -04:00
|
|
|
* Calls the Q_onAssert() callback if ever executed. This assertion
|
2015-05-14 16:05:04 -04:00
|
|
|
* takes the user-supplied parameter @p id_ to identify the location of
|
2014-04-13 21:35:34 -04:00
|
|
|
* this assertion within the file. This avoids the volatility of using
|
|
|
|
* line numbers, which change whenever a line of code is added or removed
|
|
|
|
* upstream from the assertion.
|
|
|
|
*
|
2015-05-14 16:05:04 -04:00
|
|
|
* @param[in] id_ ID number (unique within the module) of the assertion
|
2014-04-13 21:35:34 -04:00
|
|
|
*
|
2015-05-14 16:05:04 -04:00
|
|
|
* @note Does noting if assertions are disabled with the #Q_NASSERT switch.
|
2012-08-14 18:00:48 -04:00
|
|
|
*/
|
|
|
|
#define Q_ERROR_ID(id_) \
|
2020-03-17 21:33:58 -04:00
|
|
|
Q_onAssert(&Q_this_module_[0], (id_))
|
2012-08-14 18:00:48 -04:00
|
|
|
|
2014-04-13 21:35:34 -04:00
|
|
|
#endif /* Q_NASSERT */
|
2012-08-14 18:00:48 -04:00
|
|
|
|
2022-04-19 19:23:30 -04:00
|
|
|
/*==========================================================================*/
|
2012-12-10 16:01:54 -05:00
|
|
|
#ifdef __cplusplus
|
|
|
|
extern "C" {
|
|
|
|
#endif
|
|
|
|
|
2020-03-17 21:33:58 -04:00
|
|
|
#ifndef Q_NORETURN
|
|
|
|
/*! no-return function specifier */
|
|
|
|
#define Q_NORETURN void
|
|
|
|
#endif /* Q_NORETURN */
|
|
|
|
|
2022-04-19 19:23:30 -04:00
|
|
|
/*! Callback function invoked in case of any assertion failure.
|
2022-05-09 14:52:11 -04:00
|
|
|
* @details
|
2014-04-13 21:35:34 -04:00
|
|
|
* This is an application-specific callback function needs to be defined in
|
|
|
|
* the application to perform the clean system shutdown and perhaps a reset.
|
|
|
|
*
|
2015-05-14 16:05:04 -04:00
|
|
|
* @param[in] module name of the file/module in which the assertion failed
|
2015-12-31 14:56:37 -05:00
|
|
|
* (constant, zero-terminated C string)
|
2020-03-17 21:33:58 -04:00
|
|
|
* @param[in] location location of the assertion within the module. This could
|
2015-09-29 11:34:38 -04:00
|
|
|
* be a line number or a user-specified ID-number.
|
2014-04-13 21:35:34 -04:00
|
|
|
*
|
2015-05-14 16:05:04 -04:00
|
|
|
* @note This callback function should _not_ return, as continuation after
|
2014-04-13 21:35:34 -04:00
|
|
|
* an assertion failure does not make sense.
|
|
|
|
*
|
2015-05-14 16:05:04 -04:00
|
|
|
* @note The Q_onAssert() function is the last line of defense after the
|
2014-04-13 21:35:34 -04:00
|
|
|
* system failure and its implementation shouild be very __carefully__
|
|
|
|
* designed and __tested__ under various fault conditions, including but
|
|
|
|
* not limited to: stack overflow, stack corruption, or calling Q_onAssert()
|
|
|
|
* from an interrupt.
|
2012-12-10 16:01:54 -05:00
|
|
|
*
|
2015-05-14 16:05:04 -04:00
|
|
|
* @note It is typically a __bad idea__ to implement Q_onAssert() as an
|
2014-04-13 21:35:34 -04:00
|
|
|
* endless loop that ties up the CPU. During debuggin, Q_onAssert() is an
|
|
|
|
* ideal place to put a breakpoint.
|
|
|
|
*
|
|
|
|
* Called by the following macros: #Q_ASSERT, #Q_REQUIRE, #Q_ENSURE,
|
|
|
|
* #Q_ERROR, #Q_ALLEGE as well as #Q_ASSERT_ID, #Q_REQUIRE_ID, #Q_ENSURE_ID,
|
|
|
|
* #Q_ERROR_ID, and #Q_ALLEGE_ID.
|
2012-12-10 16:01:54 -05:00
|
|
|
*/
|
2022-04-19 19:23:30 -04:00
|
|
|
Q_NORETURN Q_onAssert(char const * const module, int_t const location);
|
2012-12-10 16:01:54 -05:00
|
|
|
|
|
|
|
#ifdef __cplusplus
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2022-04-19 19:23:30 -04:00
|
|
|
/*! Assertion for checking preconditions.
|
2022-05-09 14:52:11 -04:00
|
|
|
* @details
|
2014-04-13 21:35:34 -04:00
|
|
|
* This macro is equivalent to #Q_ASSERT, except the name provides a better
|
|
|
|
* documentation of the intention of this assertion.
|
|
|
|
*
|
2015-05-14 16:05:04 -04:00
|
|
|
* @param[in] test_ Boolean expression
|
2012-08-14 18:00:48 -04:00
|
|
|
*/
|
|
|
|
#define Q_REQUIRE(test_) Q_ASSERT(test_)
|
|
|
|
|
2022-04-19 19:23:30 -04:00
|
|
|
/*! Assertion for checking preconditions with user-specified assertion-id.
|
2022-05-09 14:52:11 -04:00
|
|
|
* @details
|
2014-04-13 21:35:34 -04:00
|
|
|
* Equivalent to #Q_ASSERT_ID, except the macro name provides a better
|
|
|
|
* documentation of the intention of this assertion.
|
|
|
|
*
|
2015-05-14 16:05:04 -04:00
|
|
|
* @param[in] id_ ID number (unique within the module) of the assertion
|
|
|
|
* @param[in] test_ Boolean expression
|
2012-08-14 18:00:48 -04:00
|
|
|
*/
|
2015-05-14 16:05:04 -04:00
|
|
|
#define Q_REQUIRE_ID(id_, test_) Q_ASSERT_ID((id_), (test_))
|
2012-08-14 18:00:48 -04:00
|
|
|
|
2022-04-19 19:23:30 -04:00
|
|
|
/*! Assertion for checking postconditions.
|
2022-05-09 14:52:11 -04:00
|
|
|
* @details
|
2022-04-19 19:23:30 -04:00
|
|
|
* Equivalent to #Q_ASSERT, except the macro name provides a better
|
2014-04-13 21:35:34 -04:00
|
|
|
* documentation of the intention of this assertion.
|
|
|
|
*
|
2015-05-14 16:05:04 -04:00
|
|
|
* @param[in] test_ Boolean expression
|
2012-08-14 18:00:48 -04:00
|
|
|
*/
|
2014-04-13 21:35:34 -04:00
|
|
|
#define Q_ENSURE(test_) Q_ASSERT(test_)
|
2012-08-14 18:00:48 -04:00
|
|
|
|
2022-04-19 19:23:30 -04:00
|
|
|
/*! Assertion for checking postconditions with user-specified assertion-id.
|
2022-05-09 14:52:11 -04:00
|
|
|
* @details
|
2014-04-13 21:35:34 -04:00
|
|
|
* Equivalent to #Q_ASSERT_ID, except the name provides a better documentation
|
|
|
|
* of the intention of this assertion.
|
|
|
|
*
|
2015-05-14 16:05:04 -04:00
|
|
|
* @param[in] id_ ID number (unique within the module) of the assertion
|
|
|
|
* @param[in] test_ Boolean expression
|
2012-08-14 18:00:48 -04:00
|
|
|
*/
|
2015-05-14 16:05:04 -04:00
|
|
|
#define Q_ENSURE_ID(id_, test_) Q_ASSERT_ID((id_), (test_))
|
2012-08-14 18:00:48 -04:00
|
|
|
|
2022-04-19 19:23:30 -04:00
|
|
|
/*! Assertion for checking invariants.
|
2022-05-09 14:52:11 -04:00
|
|
|
* @details
|
2014-04-13 21:35:34 -04:00
|
|
|
* Equivalent to #Q_ASSERT, except the macro name provides a better
|
|
|
|
* documentation of the intention of this assertion.
|
|
|
|
*
|
2015-05-14 16:05:04 -04:00
|
|
|
* @param[in] test_ Boolean expression
|
2012-08-14 18:00:48 -04:00
|
|
|
*/
|
2014-04-13 21:35:34 -04:00
|
|
|
#define Q_INVARIANT(test_) Q_ASSERT(test_)
|
2012-08-14 18:00:48 -04:00
|
|
|
|
2022-04-19 19:23:30 -04:00
|
|
|
/*! Assertion for checking invariants with user-specified assertion-id.
|
2022-05-09 14:52:11 -04:00
|
|
|
* @details
|
2014-04-13 21:35:34 -04:00
|
|
|
* Equivalent to #Q_ASSERT_ID, except the macro name provides a better
|
|
|
|
* documentation of the intention of this assertion.
|
|
|
|
*
|
2015-05-14 16:05:04 -04:00
|
|
|
* @param[in] id_ ID number (unique within the module) of the assertion
|
|
|
|
* @param[in] test_ Boolean expression
|
2012-08-14 18:00:48 -04:00
|
|
|
*/
|
2015-05-14 16:05:04 -04:00
|
|
|
#define Q_INVARIANT_ID(id_, test_) Q_ASSERT_ID((id_), (test_))
|
2012-08-14 18:00:48 -04:00
|
|
|
|
2022-04-19 19:23:30 -04:00
|
|
|
/*! Static (compile-time) assertion.
|
2022-05-09 14:52:11 -04:00
|
|
|
* @details
|
2014-04-13 21:35:34 -04:00
|
|
|
* This type of assertion deliberately causes a compile-time error when
|
2015-05-14 16:05:04 -04:00
|
|
|
* the @p test_ evaluates to FALSE. The macro exploits the fact that in C/C++
|
2014-04-13 21:35:34 -04:00
|
|
|
* a dimension of an array cannot be negative. The compile-time assertion has
|
|
|
|
* no runtime side effects.
|
|
|
|
*
|
2015-05-14 16:05:04 -04:00
|
|
|
* @param[in] test_ Compile-time Boolean expression
|
2012-08-14 18:00:48 -04:00
|
|
|
*/
|
2019-01-14 12:06:15 -05:00
|
|
|
#define Q_ASSERT_STATIC(test_) \
|
|
|
|
extern int_t Q_assert_static[(test_) ? 1 : -1]
|
|
|
|
|
|
|
|
#define Q_ASSERT_COMPILE(test_) Q_ASSERT_STATIC(test_)
|
2012-08-14 18:00:48 -04:00
|
|
|
|
2018-05-10 14:39:45 -04:00
|
|
|
/*! Helper macro to calculate static dimension of a 1-dim @p array_ */
|
2020-07-18 17:58:58 -04:00
|
|
|
#define Q_DIM(array_) (sizeof(array_) / sizeof((array_)[0U]))
|
2018-05-10 14:39:45 -04:00
|
|
|
|
2019-10-27 12:26:31 -04:00
|
|
|
#endif /* QASSERT_H */
|