MSVS 社区 2022 不允许使用带有 cout 的 constexpr,但 gcc 允许。哪个是正确的?

问题描述 投票:0回答:1

以下代码无法在 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++ function constexpr
1个回答
0
投票

在 C++23 之前,有一条规则:如果

constexpr
函数永远无法在编译时执行,编译器可以(但不必)对此进行诊断。

从C++23开始,没有这样的规则

你的

logError()
无法在编译时执行(因为
cout
),所以在C++23之前它是非法的。

由于您的

sqrt()
始终尝试从
if (std::is_constant_evaluated())
调用非 constexpr 函数,因此在编译时使用时总是会导致编译错误。 (在 C++23 之前,即使未使用它也是非法的,请参见上文。)

© www.soinside.com 2019 - 2024. All rights reserved.