为什么在 consteval 函数中使用 std::reverse 虽然不是 constexpr 但确实可以编译
Why does std::reverse used in consteval function does compile though not constexpr
在 CompilerExplorer 上使用这个小代码片段,std=c++20 for x86-64 clang 11.0.0 编译并运行。
#include <algorithm>
#include <array>
consteval std::array<double,2> gof()
{
std::array<double,2> x{ 3., 2.};
std::reverse(begin(x),end(x));
return x;
}
int
main(int argc, char *argv[])
{
return gof().at(0);
}
但是在具有相同设置的 CompilerExplorer 上 clang-tidy 产生
clang-tidy (trunk) #1 with x86-64 clang 11.0.0
<source>:14:12: error: call to consteval function 'gof' is not a constant expression [clang-diagnostic-error]
return gof().at(0);
^
<source>:7:5: note: non-constexpr function 'reverse<double *>' cannot be used in a constant expression
std::reverse(begin(x),end(x));
^
<source>:14:12: note: in call to 'gof()'
return gof().at(0);
^
/opt/compiler-explorer/gcc-9.2.0/lib/gcc/x86_64-linux-gnu/9.2.0/../../../../include/c++/9.2.0/bits/stl_algo.h:1180:5: note: declared here
reverse(_BidirectionalIterator __first, _BidirectionalIterator __last)
^
clang-tidy 的结果是我所期望的。为什么 clang 处理方式不同?
std::reverse
在 C++20 中是 constexpr
(问题标题另有暗示?),因此 gof()
中没有任何内容阻止它成为有效的常量表达式。
libstdc++ 实现了 constexpr
的改变,而 libc++ 还没有。因此,如果您使用 libstdc++(就像 Clang 在 Compiler Explorer 上默认使用的那样),它会正常工作。但是如果你使用 libc++ explicitly,那么它会因为你预期的原因而失败(std::reverse
不是 constexpr
这使得 gof()
不能成为常量表达式)。 clang-tidy 看起来它使用的是较旧版本的 libstdc++(从您粘贴的错误来看是 9.2),这是在 libstdc++ 实施 constexpr
更改之前。
所以基本上,您只是跨越了 constexpr
支持的前沿。
在 CompilerExplorer 上使用这个小代码片段,std=c++20 for x86-64 clang 11.0.0 编译并运行。
#include <algorithm>
#include <array>
consteval std::array<double,2> gof()
{
std::array<double,2> x{ 3., 2.};
std::reverse(begin(x),end(x));
return x;
}
int
main(int argc, char *argv[])
{
return gof().at(0);
}
但是在具有相同设置的 CompilerExplorer 上 clang-tidy 产生
clang-tidy (trunk) #1 with x86-64 clang 11.0.0
<source>:14:12: error: call to consteval function 'gof' is not a constant expression [clang-diagnostic-error]
return gof().at(0);
^
<source>:7:5: note: non-constexpr function 'reverse<double *>' cannot be used in a constant expression
std::reverse(begin(x),end(x));
^
<source>:14:12: note: in call to 'gof()'
return gof().at(0);
^
/opt/compiler-explorer/gcc-9.2.0/lib/gcc/x86_64-linux-gnu/9.2.0/../../../../include/c++/9.2.0/bits/stl_algo.h:1180:5: note: declared here
reverse(_BidirectionalIterator __first, _BidirectionalIterator __last)
^
clang-tidy 的结果是我所期望的。为什么 clang 处理方式不同?
std::reverse
在 C++20 中是 constexpr
(问题标题另有暗示?),因此 gof()
中没有任何内容阻止它成为有效的常量表达式。
libstdc++ 实现了 constexpr
的改变,而 libc++ 还没有。因此,如果您使用 libstdc++(就像 Clang 在 Compiler Explorer 上默认使用的那样),它会正常工作。但是如果你使用 libc++ explicitly,那么它会因为你预期的原因而失败(std::reverse
不是 constexpr
这使得 gof()
不能成为常量表达式)。 clang-tidy 看起来它使用的是较旧版本的 libstdc++(从您粘贴的错误来看是 9.2),这是在 libstdc++ 实施 constexpr
更改之前。
所以基本上,您只是跨越了 constexpr
支持的前沿。