折叠表达式中自赋值逗号运算符操作数的未定义行为警告



我收到GCC 10.1关于可能的未定义行为的警告。叮当10没有警告。

warning: operation on 'init' may be undefined [-Wsequence-point]
|     (x = ... = (init = fold_op(init, elements), 0));
|                   ~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~

以下是导致警告的代码段:

template <typename T, typename BinaryOp, typename... Pack>
constexpr auto reverse_reduce(T init, BinaryOp&& fold_op, Pack&&... elements) -> T
{
auto x = 0;
(x = ... = (init = fold_op(init, elements), 0));
return init;
}

它使用operator=和折叠表达式技巧对参数包执行反向"迭代"。

海湾合作委员会在这里警告是正确的吗?还是定义明确的行为?

这是我在重现错误时所能做到的最小

auto x = 0;
auto i = 0;
((x = (i = i, 0)) = (i = i, 0))

我读到的关于序列点、计算顺序和运算符优先级/关联性的所有内容都让我认为这是很好的定义,但规则太多了,我不是专家。

让我相信警告是正确的一件事是,当我将结果分配给 clang 中的constexpr变量时,结果与非constexpr评估中的结果不同。

您可以使用 lambda 来消除警告。

例:

template <typename T, typename BinaryOp, typename... Pack>
constexpr auto reverse_reduce(T init, BinaryOp&& fold_op, Pack&&... elements) -> T {
auto x = 0;
auto inner = [&](const auto& v) {init = fold_op(init, v); };
(x = ... = (inner(elements), 0));
return init;
}

相关内容

  • 没有找到相关文章

最新更新