C++ Logo

STD-DISCUSSION

Advanced search

Subject: Re: Anonymous unions with non-trivial member types
From: Andrew Schepler (aschepler_at_[hidden])
Date: 2020-08-29 12:02:07


On Fri, Aug 28, 2020 at 7:36 AM Yongwei Wu via Std-Discussion <
std-discussion_at_[hidden]> wrote:

> ...
>
> struct StringIntChar {
> enum { String, Int, Char } type;
> ~StringIntChar()
> {
> if (type == String) {
> string_value.~string();
> }
> }
> union {
> string string_value;
> int int_value;
> char char_value;
> };
> };
>
> ...
>

 I do see an issue here with the Standard wording. It appears the intent
was to allow code like this, but I think by a strict reading, the
~StringIntChar destructor is ill-formed.

The anonymous union type has a destructor which is implicitly declared as
deleted. For any other special member function, this deleted member isn't
necessarily a problem for the containing class StringIntChar, since a
user-defined special member just won't call the member of the anonymous
union. But for destructors, [class.dtor]/14 says

After executing the body of the destructor and destroying any objects with
> automatic storage duration allocated within the body, a destructor for
> class X calls the destructors for X's direct non-variant non-static data
> members, the destructors for X's non-virtual direct base classes and, if X
> is the most derived class ([class.base.init]), its destructor calls the
> destructors for X's virtual base classes.
>

I think the "non-variant" phrasing reflects an intent to make code like the
example valid. But the subobject whose type is the anonymous union is still
a "direct non-variant non-static data member" of StringIntChar, so any
StringIntChar destructor still involves a call to the union's deleted
destructor, and so is ill-formed.

Worth a Defect Report, does anyone think?

-- Andrew Schepler



STD-DISCUSSION list run by std-discussion-owner@lists.isocpp.org

Older Archives on Google Groups