Full name of submitter (unless configured in github; will be published with the issue): Jiang An
Reference (section label): [dcl.init.aggr]
Link to reflector thread (if any):
Issue description:
Consider the following example:
// assuming that there're padding bytes in A and B, which holds for most implementations
struct A {
char c;
int i;
};
struct B {
B() = default; // making B not an aggregate (since C++20)
char c;
int i;
};
void test() {
auto a1 = A();
auto a2 = A{};
auto a3 = A{.c{}};
auto b1 = B();
auto b2 = B{};
}
As B is not an aggregate and has an eligible default constructor, b1 and b2 are both zero-initialized first and get their padding bits zeroed (per [dcl.init.list] and [dcl.init.general]). See also CWG694.
a1 is also zero-initialized. However, [dcl.init.list] specifies that aggregate initialization, but not value initialization is performed for a2. In [dcl.init.aggr], there's nothing specifying zero-initializing for the whole class object, which leaves padding bits uninitialized.
Note that in C (since C23, via WG14 N2796), an empty initializer causes padding bits zero-initialized. Perhaps it would be better to adopt such behavior for C++ to improve compatibility with C, and reduce the semantic difference between A() and A{}.
Moreover (beyond the compatibility issue with C), it would be surprising a3 has less zero-initialized contents than a2. So I think it would be better to just perform zero-initialization in all forms of aggregate initialization, although we might need to precisely handle unions.
Suggested resolution:
Full name of submitter (unless configured in github; will be published with the issue): Jiang An
Reference (section label): [dcl.init.aggr]
Link to reflector thread (if any):
Issue description:
Consider the following example:
As
Bis not an aggregate and has an eligible default constructor,b1andb2are both zero-initialized first and get their padding bits zeroed (per [dcl.init.list] and [dcl.init.general]). See also CWG694.a1is also zero-initialized. However, [dcl.init.list] specifies that aggregate initialization, but not value initialization is performed fora2. In [dcl.init.aggr], there's nothing specifying zero-initializing for the whole class object, which leaves padding bits uninitialized.Note that in C (since C23, via WG14 N2796), an empty initializer causes padding bits zero-initialized. Perhaps it would be better to adopt such behavior for C++ to improve compatibility with C, and reduce the semantic difference between
A()andA{}.Moreover (beyond the compatibility issue with C), it would be surprising
a3has less zero-initialized contents thana2. So I think it would be better to just perform zero-initialization in all forms of aggregate initialization, although we might need to precisely handle unions.Suggested resolution: