神秘的UB /段错误只在gcc上 - 代码是不正确的?

Vit*_*meo 8 c++ gcc segmentation-fault undefined-behavior c++17

#include <utility>

template <typename P, typename F>
struct foo
{
    P _p;
    int i{0};

    foo(P&& p, F) : _p{std::move(p)} { }

    template <typename... Cs>
    void up(Cs&... cs)
    {
        if constexpr(sizeof...(Cs) == 2) { down(cs...); }
        else { _p.up(*this, cs...); }
    }

    void down() { --i; }

    template <typename C, typename... Cs>
    void down(C& c, Cs&... cs)
    {
        [&] { [&] { c.down(cs...); }(); }();
    }
};

int main()
{
    auto f = foo{foo{foo{0, 0}, 0}, 0};
    f.up();
}
Run Code Online (Sandbox Code Playgroud)

上面的代码片段:

  • 使用g ++ 7.1和trunk编译时,始终会执行段错误-O0.

  • 始终报告使用g ++ 7.1和trunk编译时的执行错误,具有任何优化级别和任一-fsanitize=address-fsanitize=undefined.

  • 切勿使用clang ++ 5和trunk报告段或报告任何清洁剂错误.

wandbox上的实例


采取以下任何措施:

  • 摆脱--i;down().

  • 更改[&] { [&] { c.down(cs...); }(); }();[&] { c.down(cs...); }();.

  • 相应地删除typename F和更新构造函数.

  • 更改foo{foo{foo{0, 0}, 0}, 0}foo{foo{0, 0}, 0}.

修复了分段故障并防止任何消毒剂错误.

这里发生了什么?我的代码是不正确的,还是这是一个奇怪的gcc错误导致错误的汇编?