C++ knows assert()
which allows runtime checks that compile to nothing in dependence of NDEBUG
.
I would like to replace that macro using compiler-code and avoiding the preprocessor. I need to do the following:
false
NDEBUG
buildsBreaking/terminating the application is easy.
In C++20 there is std::experimental::source_location
which I can use to get the code location of the assertion.
A compile time conditional could be done using requires
or constexpr if
However I do not know how I could avoid the evaluation of the expression. When implementing myAssert(expression)
as a function, I need to pass the expression result as a function argument which means it is evaluated anyway, even if the parameter is not used inside the function.
Is there a way to solve this in C++20?
EDIT: A templated example:
template <typename T> requires (gDebug)
void assertTrue(const T& pResult, const std::experimental::source_location& pLocation) noexcept
{
if (!static_cast<bool>(pResult))
{
// error handling
}
}
template <typename T> requires (!gDebug)
void assertTrue(const T&) noexcept
{
}
I suppose you are talking about the case when you disabled debugging and you want the function to be a noop. I see 2 options:
You can use a macro. Macros can be misused, but they have their place and "passing an expression" without evaluating it is a case for a macro.
Alternatively, pass a callable that returns the result you want to assert for. Only call it when gDebug == True
:
template <typename F> requires (gDebug)
void assertTrue(const F& f, const std::experimental::source_location& pLocation) noexcept
{
if (!static_cast<bool>(f()))
{
// error handling
}
}
Though this will make the call rather verbose. For example one that fails always:
assertTrue( [](){ return false; });