c++ - 结构的聚合初始化,使用它自己的数据成员

标签 c++ aggregate-initialization

这是关于此的第 n 个问题,但我找不到完全相同的重复项...

假设如下代码:

#include <iostream>

struct S {
    int x;
    int y;
};

class C {
public:
    S s;
    C() : s{123, s.x} {}
};

int main() {
     std::cout << C().s.y << '\n';
}

这样初始化s.y可以吗? (只有 JetBrains 的 ReSharper 用以下方式提示它:Object member this->s.x might not be initialized)。

如果有人用标准的引用来确认他们的答案,那就太好了。

最佳答案

来自 C++14

8.5.1 聚合 [dcl.init.aggr]

1 聚合是一个数组或一个类(第 9 条),没有用户提供的构造函数(12.1),没有私有(private)或 protected 非静态数据成员(第 11 条),无基类(第 10 条),无虚函数(10.3)。

2 当聚合被初始化列表初始化时,如 8.5.4 中所指定,初始化列表的元素 以递增的下标或成员顺序作为聚合成员的初始值设定项。

这意味着s.x首先用123初始化,然后s.y用s.x初始化。

没有优化,GCC 6.3 生成

C::C():
        push    rbp
        mov     rbp, rsp
        mov     QWORD PTR [rbp-8], rdi
        mov     rax, QWORD PTR [rbp-8] # read address of s
        mov     DWORD PTR [rax], 123   # write 123 to s.x (offset 0 from s)
        mov     rax, QWORD PTR [rbp-8] # read address of s again
        mov     edx, DWORD PTR [rax]   # read contents of s.x to edx
        mov     rax, QWORD PTR [rbp-8] # read address of s
        mov     DWORD PTR [rax+4], edx # write s.y (offset 4 from s)
        nop
        pop     rbp
        ret

这与标准所说的一致。

关于c++ - 结构的聚合初始化,使用它自己的数据成员,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43234115/

相关文章:

c++ - std::vector 的协变包装器

c++ - 对使用带有 istream 参数的构造函数感到困惑

c++ - QTableWidget - QMenu 上下文菜单 - AddAction 插槽不调用函数

c++ - 初始化中的评估顺序

c++ - 同时具有聚合初始化和模板推导

c++ - 如何在关联指针时编写无错误代码?

c++ - 为什么下面的代码用 `c++03` 编译而不用 `c++11`

c++ - 在聚合初始化列表中的给定位置,传递到先前位置的值是否可以安全地从相应成员读取?

c++ - 聚合初始化期间无法访问继承的结构成员

带有 char 数组的 C++ 结构以不寻常的方式初始化为零