I wrote a few "compile-time math" functions in a utility header file and I'm using static_assert
statements to test them.
Whether to keep these statements with the production code or with the test code (in a dummy 'unit test' *.cpp) is probably mostly a matter of style/preference (comments welcome, though).
But what about performance (compilation time) if we had lots of tests? If I keep the static_assert
in the production code header, will they be run for every compilation unit I include the header in? Or is the compiler somehow 'smart' about static_assert
statements?
One of the more trivial functions as an example:
/** Calculate the sum of a given number of args in parameter pack - starting from the given firstSummand (1-based) */
template<typename... Args, typename T = typename std::common_type<Args...>::type>
constexpr T sumOverRange(int firstSummand, int numSummands, Args... args) noexcept
{
firstSummand = std::max<int>(firstSummand, 1);
numSummands = std::min<int>(numSummands, sizeof...(args)-firstElement+1);
T sum {0};
T values[] { args... };
for (int i=firstSummand; i < firstSummand+numSummands; ++i) {
sum += values[i-1];
}
return sum;
}
static_assert(sumOverRange(2, 3, 2, 2, 3, -4) == 1, "");
static_assert(sumOverRange(1, 0, 2, 2, 3) == 0, "zero summands");
static_assert(sumOverRange(2, -1, 2, 2, 3) == 0, "negative num summands");
static_assert(sumOverRange(-1, 1, 2, 2, 3) == 2, "negative range start");
If I keep the static_assert in the production code header, will they be run for every compilation unit I include the header in?
Yes. An include does nothing else then inserting the content of the included file into the including file. To the C++ compiler there's no difference whether your code comes from a header or not. The static_assert will therefore be always evaluated.
Or is the compiler somehow 'smart' about static_assert statements?
It could be. But most compilers are probably not very smart about it, since the focus of compiler development has traditionally been fast executables, not evaluating programs fast at compilation-time.
But what about performance (compilation time) if we had lots of tests?
Well, the compiler will have to execute your code. This will probably be slower than compiling and running the respective code in absolute time, but asymptotically as fast.
You maybe interested in this discussion: https://lists.llvm.org/pipermail/cfe-dev/2019-July/062799.html
As a practical recommendation: Since you are apparently using static_asserts to unit test your code, I would recommend to remove them from the header. Tests should always be separated from the tested code.