分配给临时的 GCC 9.3 错误或格式错误 code/UB?

Assignment to temporary, GCC 9.3 bug or ill formed code/UB?

这个问题很短,对于缺乏细节,我很抱歉我 运行 时间不够。

我 运行 对我来说似乎是一个错误。您可以在此处找到代码:https://godbolt.org/z/eWMbb7qrK。 这段代码至少从版本 8 开始就可以在 clang 上编译。但是在 gcc 上,它不会在 10.1 之前编译(我只测试了 God bolt 上可用的编译器)。

因此,虽然它已在最新版本中得到修复,但我想知道是否有解决方案可以使此代码或“旧”编译器正常工作,并尽可能小地进行更改。

提前致谢。

#include <iostream>

class A {
 public:
  constexpr A() : i_{} {}
  constexpr A(const A&) = default;
  template <int i>
  constexpr A(const char (&the_data)[i]) : i_{i} {}

  int i_;
};

int main() {
  {
    A a{"aze"};
    std::cout << a.i_ << '\n';
  }
  {
    A a{A{"aze"}};
    std::cout << a.i_ << '\n';
  }
  {
    A a{};
    a = A{"aze"};
    std::cout << a.i_ << '\n';
  }
  {
    static_assert((A{} = A{"aze"}).i_ == 4, "");
    std::cout << (A{} = A{"aze"}).i_ << '\n';
  }
}

不确定失败的确切原因,但您可以更改

(A{} = A{"aze"}).i_

成为

A{"aze"}.i_

它在旧版本中编译:live example

默认的 constexpr 赋值运算符在 gcc-9.4 和之前的版本上看起来有问题。自己定义。

#include <iostream>

struct A {
  constexpr A() : i_{} {}
  constexpr A(const A&) = default;
  template <int i>
  constexpr A(const char (&the_data)[i]) : i_{i} {}
  constexpr A& operator=(A const& other)
  { i_ = other.i_; return *this; }

  int i_;
};


int main() {
  {
    static_assert((A{} = A{"aze"}).i_ == 4, "");
  }
}

演示:https://godbolt.org/z/hGjEK37Yo