I'm saying a conditional branch that offers a different path of execution for a constant evaluation than for a runtime evaluation gives you a function that behaves differently in different contexts.
In Rust, for instance, constant functions have to evaluate the same in both compile time and run time - you can't have a different code path depending on which. If you want that, make two functions.
constexpr bool test_is_even() {
assert(is_even(0));
assert(!is_even(1));
// … more test coverage
return true;
}
int main() {
test_is_even(); // runtime coverage
static_assert(test_is_even()); // compile-time coverage
This lets us run all test cases at both runtime and compiletime. (The static_assert performs constant evaluation, and if an assert within test_is_even would fail, it won’t be a constant expression.)
But then you can't have generic functions that are efficient at run-time and work at compile-time ?
This feature is added to c++ not for fun but because if you can't have a run-time branch that will do some AVX-fu, or invoke some runtime function from BLAS or LAPACK, the whole "evaluate at compile-time" thing is... Not useless but not far either
In Rust, for instance, constant functions have to evaluate the same in both compile time and run time - you can't have a different code path depending on which. If you want that, make two functions.
Trivially:
How would you unit test this in a way that catches that only the constant evaluation is broken?