diff --git a/include/sys/util.h b/include/sys/util.h index 2231931a679..652a83d6421 100644 --- a/include/sys/util.h +++ b/include/sys/util.h @@ -89,10 +89,20 @@ constexpr size_t ARRAY_SIZE(T(&)[N]) { return N; } #define INLINE #endif +/** @brief Return larger value of two provided expressions. + * + * @note Arguments are evaluated twice. See Z_MAX for GCC only, single + * evaluation version. + */ #ifndef MAX #define MAX(a, b) (((a) > (b)) ? (a) : (b)) #endif +/** @brief Return smaller value of two provided expressions. + * + * @note Arguments are evaluated twice. See Z_MIN for GCC only, single + * evaluation version. + */ #ifndef MIN #define MIN(a, b) (((a) < (b)) ? (a) : (b)) #endif diff --git a/include/toolchain/gcc.h b/include/toolchain/gcc.h index 69371870a3f..25c4d08871f 100644 --- a/include/toolchain/gcc.h +++ b/include/toolchain/gcc.h @@ -415,4 +415,32 @@ do { \ __asm__ __volatile__ ("" ::: "memory"); \ } while (false) +/** @brief Return larger value of two provided expressions. + * + * Macro ensures that expressions are evaluated only once. + * + * @note Macro has limited usage compared to the standard macro as it cannot be + * used: + * - to generate constant integer, e.g. __aligned(Z_MAX(4,5)) + * - static variable, e.g. array like static u8_t array[Z_MAX(...)]; + */ +#define Z_MAX(a, b) ({ \ + /* random suffix to avoid naming conflict */ \ + __typeof__(a) _value_a_ = (a); \ + __typeof__(b) _value_b_ = (b); \ + _value_a_ > _value_b_ ? _value_a_ : _value_b_; \ + }) + +/** @brief Return smaller value of two provided expressions. + * + * Macro ensures that expressions are evaluated only once. See @ref Z_MAX for + * macro limitations. + */ +#define Z_MIN(a, b) ({ \ + /* random suffix to avoid naming conflict */ \ + __typeof__(a) _value_a_ = (a); \ + __typeof__(b) _value_b_ = (b); \ + _value_a_ < _value_b_ ? _value_a_ : _value_b_; \ + }) + #endif /* ZEPHYR_INCLUDE_TOOLCHAIN_GCC_H_ */