0

在 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处理它的方式不同?

4

1 回答 1

2

std::reverseconstexprC++20 中(问题标题另有暗示?),所以没有什么gof()可以阻止它成为有效的常量表达式。

libstdc++ 实现了这一constexpr改变,而 libc++ 还没有。因此,如果您使用 libstdc++(就像编译器资源管理器中默认的 clang 一样),它会正常工作。但是如果你显式地使用 libc++ ,那么它会因为你期望的原因而失败(std::reverse不是constexpr这使得gof()fail 成为一个常量表达式)。clang-tidy 看起来它使用的是旧版本的 libstdc++(您粘贴的错误为 9.2),这是在 libstdc++ 实施constexpr更改之前。

所以基本上,你只是跨越了constexpr支持的前沿。

于 2021-01-20T17:04:18.790 回答