c++ - 为什么 "missing double brace warning"用于 Clang 12 中的 BaseClass 聚合初始化而不是 Clang 13 或 GCC 11?

标签 c++ language-lawyer

此代码在 GCC 11 和 Clang 13(C++20 模式)中编译时没有警告

struct A {
    int x, y;

};

struct B : A { };

int main () {
    A a{1,2};
    B b{3,4};  // Clang 12 wants B b{{3,4}}

    return a.x * b.x + a.y * b.y;

}

但是在 Clang 12 中我们得到

<source>:10:9: warning: suggest braces around initialization of subobject [-Wmissing-braces]
    B b{3,4};

https://godbolt.org/z/Kdnon9575

可能与:

Why does Clang 12 refuse to initialize aggregates in the C++20 way?

和这些论文

http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2019/p0960r3.html

http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2019/p1975r0.html

C++20 是否正式支持单大括号(没有警告)来初始化这些简单的 POD 派生类?如果是这样,标准在哪里说的,所以我们可以依赖它?

在 C++17 中,双括号是必需的,以避免警告,是吗?

在 C++14 中,单括号是一个硬错误,因为派生结构不是聚合,是吗?

最佳答案

C++17 和 C++20,https://timsong-cpp.github.io/cppwp/n4659/dcl.init.aggr#12https://timsong-cpp.github.io/cppwp/n4868/dcl.init.aggr#15 ,分别允许聚合初始化的大括号省略:

Braces can be elided in an initializer-list as follows. If the initializer-list begins with a left brace, then the succeeding comma-separated list of initializer-clauses initializes the members of a subaggregate; it is erroneous for there to be more initializer-clauses than members. If, however, the initializer-list for a subaggregate does not begin with a left brace, then only enough initializer-clauses from the list are taken to initialize the members of the subaggregate; any remaining initializer-clauses are left to initialize the next member of the aggregate of which the current subaggregate is a member.

OP 示例中的 B 类是 C++17 和 C++20 中的聚合(根据 C++17 的 P0017R1 及其主要对 [dcl.init.aggr]/1 的更新),其中符合条件的要求聚合在基类要求方面变得更加宽松。

An aggregate is an array or a class ([class]) with

  • [...]
  • (C++14) no base classes
  • (C++17 and C++20) no virtual, private, or protected base classes

现在,Clang 诊断只是一开始的警告,从 Clang 13 开始,它似乎(我认为是正确的)已被删除,以用于具有基类的聚合的大括号省略初始化。警告可能是来自 C++14 的残余极端情况,其中 B 不是聚合,但程序由于无效的初始化形式而格式错误。

关于c++ - 为什么 "missing double brace warning"用于 Clang 12 中的 BaseClass 聚合初始化而不是 Clang 13 或 GCC 11?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/70672136/

相关文章:

c++ - Emacs CEDET 语义完成 "cannot find types for ..."

c++ - 动态转换 C++ 失败

C++ 数组对坐标周围的值求和

c++ - 无法使用 OOP C++ 打印堆栈项

c++ - 如何在布局中安排 QCamera 与其他小部件?

c - 使用 char * 访问 int 是否可能具有未定义的行为?

c - difftime的粒度

c++ - 如果绝对没有调用成员函数,是否允许具有不完整类型的 vector ?如果有,从什么时候开始?

c++ - SFINAE 适用于扣除但因替代而失败

C++ block scope extern declaration linkage,混淆C++标准解释