简体   繁体   English

为什么在 consteval function 中使用的 std::reverse 确实编译但不是 constexpr

[英]Why does std::reverse used in consteval function does compile though not constexpr

Using this little code snippet on CompilerExplorer with std=c++20 for x86-64 clang 11.0.0 compiles and runs.在 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);
}

But clang-tidy on CompilerExplorer with the same settings yields但是在具有相同设置的 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)
    ^

What clang-tidy yields is what I expect.整洁的产量是我所期望的。 Why does clang handle it differently?为什么 clang 处理方式不同?

std::reverse is constexpr in C++20 (the question title suggests otherwise?), so nothing in gof() prevents it from being a valid constant expression. std::reverse在 C++20 中是constexpr (问题标题另有暗示?),因此gof()中没有任何内容阻止它成为有效的常量表达式。

libstdc++ implements that constexpr change, while libc++ does not yet. libstdc++ 实现了constexpr更改,而 libc++ 还没有。 So if you use libstdc++ (as clang does by default on Compiler Explorer), it'll work fine.因此,如果您使用 libstdc++(正如 clang 在 Compiler Explorer 上默认使用的那样),它会正常工作。 But if you use libc++ explicitly , then it'll fail for the reason you expect ( std::reverse isn't constexpr which makes gof() fail to be a constant expression).但是如果你显式地使用 libc++,那么它会因为你期望的原因而失败( std::reverse不是constexpr ,这使得gof()不能成为一个常量表达式)。 clang-tidy looks like it's using an older version of libstdc++ (9.2 from the error you pasted), which was before libstdc++ implemented the constexpr change. clang-tidy 看起来它使用的是旧版本的 libstdc++(您粘贴的错误为 9.2),这是在 libstdc++ 实施constexpr更改之前。

So basically, you're just straddling the bleeding edge of constexpr support here.所以基本上,你只是跨越了constexpr支持的前沿。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 为什么 consteval function 允许未定义的行为? - Why does a consteval function allow undefined behavior? 返回constexpr的函数无法编译 - Function returning constexpr does not compile 非'constexpr' function std::to_string(int) 在 consteval lambda - non-'constexpr' function std::to_string(int) in a consteval lambda 为什么 consteval/constexpr 和模板元函数之间的编译时间存在如此巨大的差异? - Why is there such a massive difference in compile time between consteval/constexpr and template metafunctions? 为什么 `consteval` 的行为不如预期? - Why does `consteval` not behave as expected? 为什么gcc5.4不编译调用非constexpr函数的constexpr函数,而icpc编译呢? - Why gcc5.4 doesn't compile a constexpr function calling a non-constexpr function, but icpc does? 为什么GCC在编译时不评估constexpr? - Why GCC does not evaluate constexpr at compile time? 为什么递归constexpr模板值不能编译? - Why recursive constexpr template value does not compile? 为什么要编译(在初始化之前用于函数)? - Why does this compile (used in function before initialized)? 为什么在三元运算符中使用std :: ostream不能编译? - Why does std::ostream not compile when used in ternary operator?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM