static_assert 在生产代码中 header:编译时间不好?
static_assert in production code header: bad for compilation time?
我在实用程序 header 文件中编写了一些“compile-time 数学”函数,我正在使用 static_assert
语句来测试它们。
是否将这些语句与生产代码或测试代码(在虚拟 'unit test' *.cpp 中)一起保留可能主要是 style/preference 的问题(尽管欢迎评论)。
但是如果我们有很多测试,性能(编译时间)呢?如果我将 static_assert
保留在生产代码 header 中,对于我包含 header 的每个编译单元,它们都是 运行 吗?或者编译器是否以某种方式 'smart' 关于 static_assert
语句?
以其中一个比较琐碎的函数为例:
/** 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?
是的。 include 什么都不做,然后将包含文件的内容插入到包含文件中。对于 C++ 编译器,您的代码是否来自 header 没有区别。因此,static_assert 将始终被评估。
Or is the compiler somehow 'smart' about static_assert statements?
可能是。但是大多数编译器可能对此不是很聪明,因为编译器开发的重点传统上是快速可执行文件,而不是在 compilation-time.
下快速评估程序
But what about performance (compilation time) if we had lots of tests?
好吧,编译器必须执行您的代码。这可能比在绝对时间编译和 运行 相应代码慢,但渐近速度一样快。
您可能对此讨论感兴趣:https://lists.llvm.org/pipermail/cfe-dev/2019-July/062799.html
作为实用建议:由于您显然使用 static_assert 对代码进行单元测试,我建议将它们从 header 中删除。测试应始终与测试代码分开。
我在实用程序 header 文件中编写了一些“compile-time 数学”函数,我正在使用 static_assert
语句来测试它们。
是否将这些语句与生产代码或测试代码(在虚拟 'unit test' *.cpp 中)一起保留可能主要是 style/preference 的问题(尽管欢迎评论)。
但是如果我们有很多测试,性能(编译时间)呢?如果我将 static_assert
保留在生产代码 header 中,对于我包含 header 的每个编译单元,它们都是 运行 吗?或者编译器是否以某种方式 'smart' 关于 static_assert
语句?
以其中一个比较琐碎的函数为例:
/** 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?
是的。 include 什么都不做,然后将包含文件的内容插入到包含文件中。对于 C++ 编译器,您的代码是否来自 header 没有区别。因此,static_assert 将始终被评估。
Or is the compiler somehow 'smart' about static_assert statements?
可能是。但是大多数编译器可能对此不是很聪明,因为编译器开发的重点传统上是快速可执行文件,而不是在 compilation-time.
下快速评估程序But what about performance (compilation time) if we had lots of tests?
好吧,编译器必须执行您的代码。这可能比在绝对时间编译和 运行 相应代码慢,但渐近速度一样快。
您可能对此讨论感兴趣:https://lists.llvm.org/pipermail/cfe-dev/2019-July/062799.html
作为实用建议:由于您显然使用 static_assert 对代码进行单元测试,我建议将它们从 header 中删除。测试应始终与测试代码分开。