【问题标题】:Why do clang and gcc handle braced-initialization of structs with in-class initialization differently?为什么 clang 和 gcc 以不同的方式处理具有类内初始化的结构的支撑初始化?
【发布时间】:2016-04-02 03:15:37
【问题描述】:

我最近发现了 clang 和 gcc 的一个奇怪行为。我有一个结构 (MyClass),它对其成员之一 (active) 使用类内初始化:

struct MyClass {
  int something;
  bool active = true;
};

现在我尝试大括号初始化这个类。

使用 clang,我可以决定是否将 active 包含在初始化列表 (MyClass a = { 42, true};) 中 (MyClass a = { 42 };)。

但是使用 gcc,我的代码只有在不包含 active 时才能编译。否则,我会得到以下编译器错误:

 error: could not convert ‘{42, true}’ from ‘<brace-enclosed initializer list>’ to ‘MyClass’

这是一个错误吗?标准对此有何评论? VSC++呢?您会推荐哪种方式作为便携式解决方案?

在 Debian Linux 上使用 gcc 4.9 和 clang 3.5 进行测试。

【问题讨论】:

  • 你是否都在 C++14 模式下编译?
  • 是的,我愿意。我还启用了所有警告-Wall,但没有收到任何警告。
  • 在 C++11 中,一个带有 non-static in-class member initializers is not an aggregate 的类,所以这在 C++11 模式下会失败,但在 C++14 模式下应该都能成功。正如我在answer 中提到的链接问题 gcc 直到 5.0 才支持这一点。
  • @melak47 见我上面的注释

标签: c++ c++11 gcc clang c++14


【解决方案1】:

这段代码的行为在 C++11 和 C++14 之间发生了变化。

在 C++11 中,= true 的存在意味着该类不是聚合。因此,您不能使用聚合初始化。

在 C++14 中,该类仍然是一个聚合,因此您可以再次使用聚合初始化。

编译器之间的差异可以用一个比另一个更新来解释。使用compiler explorer 我看到 gcc 4.9.x 出错了,但这在 gcc 5.1 中已修复。

【讨论】:

  • 在 c++11 模式下使用 clang 支持这个假设。它抱怨和 gcc 一样的东西。
  • 我的猜测是,这在技术上是 C++ 11 模式中的一个 bug,尽管它基本上是无害的,除非您在使用此构造时专门寻找错误。
  • @MatsPetersson 在 clang 中似乎是正确的,在 g++ 中是错误的
  • @M.M:嗯,代码应该在 C++11 模式下编译吗?我的评论是对 OP 的评论,即在 C++11 模式下,它仍然可以在 clang 中编译...
  • @MatsPetersson 我认为他的意思是代码在 clang -std=c++11 中失败并在 clang -std=c++14 中成功,这是正确的行为(编译器资源管理器似乎可以承受这个)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-03-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-08-04
相关资源
最近更新 更多