https://gcc.gnu.org/bugzilla/show_bug.cgi?id=114898
Bug ID: 114898 Summary: Converting {} to a tag type should be ill-formed SFINAE-friendly Product: gcc Version: unknown Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: arthur.j.odwyer at gmail dot com Target Milestone: --- See LWG 2510, "Tag types should not be DefaultConstructible": https://cplusplus.github.io/LWG/issue2510 WG21 seems convinced that there's also a core-language issue here: https://cplusplus.github.io/CWG/issues/1518.html In the notes for LWG2510, I see: > JW [i.e. jwakely] explains that it's important that tag types cannot be > constructed from "{}" (e.g. the allocator tag in the tuple constructors). However, it looks like GCC+libstdc++ violates LWG2510 by allowing tag types to be constructible from `{}` (or at least to fail in a SFINAE-unfriendly way). // https://godbolt.org/z/cMzar8Ehf struct Widget { int i[1]; }; std::optional<Widget> r1( {{}} ); // Bug 1: GCC complains about nullopt_t's explicit ctor std::optional<Widget> r2{ {} }; // Bug 2: GCC complains about in_place_t's explicit ctor Now, according to Clang+libstdc++, Clang+libc++, and MSVC+STL, both examples should be well-formed, and should mean: - r1 is direct-initialized from {{}} i.e. a Widget with one element {} i.e. a value-initialized array of int[1]. - r2 is direct-list-initialized from {} i.e. a value-initialized Widget. In the April 2024 WG21 mailing, Brian Bi brings a paper P3112 "Specify Constructor of std::nullopt_t" motivated by this bad behavior of GCC's, https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2024/p3112r0.html but really I think it should just be a bug report, since GCC is the one compiler currently misbehaving, and jwakely was already quoted above as wanting `{}` _not_ to construct a tag type. I don't much care whether this is treated as a GCC compiler bug or a libstdc++ library bug, but at first glance it _looks_ like a compiler bug (since libstdc++ works fine with Clang). If it _is_ treated as a libstdc++ bug, you might take this opportunity to audit all of the tag types in the entire library and just make sure they're all implemented using the same consistent technique, whatever it is.