I have several brief constexpr
functions in my libraries that perform some simple calculations. I use them both in run-time and compile-time contexts.
I would like to perform some assertions in the body of these functions, however assert(...)
is not valid in a constexpr
function and static_assert(...)
can not be used to check function parameters.
Example:
constexpr int getClamped(int mValue, int mMin, int mMax) noexcept
{
assert(mMin <= mMax); // does not compile!
return mValue < mMin ? mMin : (mValue > mMax ? mMax : mValue);
}
Is there a way to check whether the function is being executed in a run-time or compile-time constant and execute the assert
only if it's being executed at run-time?
constexpr int getClamped(int mValue, int mMin, int mMax) noexcept
{
assert_if_runtime(mMin <= mMax);
return mValue < mMin ? mMin : (mValue > mMax ? mMax : mValue);
}
I believe that
assert
will work for you once g++ implements N3652, Relaxing constraints on constexpr functions. Currently, this status page indicates that this has not yet been implemented.assert
does work (in constexpr functions) on the current clang compiler shipped by Apple, with-std=c++1y
.At this time, I see nothing in the standard that assures one that
assert
will work in constexpr functions, and such an assurance would be a welcome addition to the standard (at least by me).Update
Richard Smith drew my attention to LWG 2234 submitted by Daniel Krügler which is attempting to create the assurance I refer to above.
Throwing an exception might be useful as the compiler will ignore the run-time part when it knows at compile-time that the exception is not thrown.
Live example
A refinement on Daniel Frey's answer is to use
noexcept
on theconstexpr
function to turn the runtime error into a call tostd::terminate
. Assertion failures are unrecoverable; they should halt the process immediately. Turning them into exceptions is a very bad idea.The runtime error for me looks like:
Hope that helps.