以下代码无法在 msvs 社区 2022 上编译,显示“错误 C3615:constexpr 函数 'logError' 无法生成常量表达式。”
#include <string>
#include <iostream>
constexpr void logError(const std::string& error)
{
std::cout << error << std::endl;
}
constexpr int sqrt(int x)
{
if (std::is_constant_evaluated())
{
logError("Oh no, this is not constantly evaluated");
return 30;
}
else
{
int result{};
while (result * result <= x) ++result;
return result - 1;
}
}
int c = sqrt(9);
int main() {
std::cout << c;
return 0; }
我在 godbolt.org 上用“-std=c++23 -O2”编译了它。代码已编译,但
else
块始终运行。 logError
永远不会与 if (std::is_constant_evaluated())
或 if (***!***std::is_constant_evaluated())
一起调用。那么哪个编译器是正确的?
在 C++23 之前,有一条规则:如果
constexpr
函数永远无法在编译时执行,编译器可以(但不必)对此进行诊断。
从C++23开始,没有这样的规则。
你的
logError()
无法在编译时执行(因为cout
),所以在C++23之前它是非法的。
由于您的
sqrt()
始终尝试从 if (std::is_constant_evaluated())
调用非 constexpr 函数,因此在编译时使用时总是会导致编译错误。 (在 C++23 之前,即使未使用它也是非法的,请参见上文。)