https://gcc.gnu.org/bugzilla/show_bug.cgi?id=114977
Arthur O'Dwyer <arthur.j.odwyer at gmail dot com> changed:
What |Removed |Added
----------------------------------------------------------------------------
CC| |arthur.j.odwyer at gmail dot
com
--- Comment #1 from Arthur O'Dwyer <arthur.j.odwyer at gmail dot com> ---
I just wrote this up as a new issue, before finding Mital had already filed it.
:)
Bug 115645 is probably related.
// https://godbolt.org/z/h6fE4EYE7
struct A {
explicit A();
};
struct S { int i; A a; };
S s {1}; // ill-formed
S t (1); // should be OK, but GCC rejects
The initialization of `s` is direct-list-initialization, which ends up in
https://eel.is/c++draft/dcl.init#aggr-5.2 and initializes `s.a` via
copy-initialization from an empty initializer list. This rightly gives an
error.
The initialization of `t`, though, is direct-non-list-initialization, which
ends up in https://eel.is/c++draft/dcl.init#general-16.6.2.2 and initializes
`t.a` via value-initialization. This should be OK — Clang thinks it's OK — but
GCC rejects with an error:
error: converting to 'A' from initializer list would use explicit
constructor 'A::A()'
6 | S t (1); // should be OK, but GCC rejects
| ^
See also CWG 3011, https://cplusplus.github.io/CWG/issues/3011.html
which (at least at the moment) doubles down on this intentional subtle
difference between list-initialization and direct-non-list-initialization. Mind
you, I think this difference is crazy and GCC/EDG/MSVC are probably sane *not*
to implement it; but it looks like Clang *has* implemented CWG's preferred
behavior, so if GCC wants not to implement it, you should probably speak up
louder.
P.S., in bug 115645 jwakely predicts that explicit zero-argument constructors
are rare. I disagree — every ctor you write should be explicit by default — but
I predict that parens-aggregate-initialization with the wrong number of
elements should be *very* rare (except by mistake), and so the conclusion —
that this quirk doesn't really matter — does continue to hold. :)