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.

Reply via email to