Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Does deleted destructor change aggregate initialization in C++?

The code as follows

struct B {
    ~B() = delete;
};

B * b = new B{};

fails to compile in the latest MSVC with the error:

error C2512: 'B': no appropriate default constructor available
note: Invalid aggregate initialization

At the same time both GCC and Clang do not see anything wrong in the code, demo: https://gcc.godbolt.org/z/va9vcsEed

Is it right to assume just a bug in MSVC?

Overall, does the presence or deletion of the destructor change any rule of the aggregate initialization?

like image 249
Fedor Avatar asked Dec 11 '21 10:12

Fedor


People also ask

What is aggregate initialization?

Explanation. Aggregate initialization is a form of list-initialization, which initializes aggregates. An aggregate is an object of the type that is one of the following. array type. class type (typically, struct or union), that has.

What is brace initialization?

If a type has a default constructor, either implicitly or explicitly declared, you can use brace initialization with empty braces to invoke it. For example, the following class may be initialized by using both empty and non-empty brace initialization: C++ Copy.

What is aggregate type C++?

An aggregate type is a structure, union, or array type. If an aggregate type contains members of aggregate types, the initialization rules apply recursively.


1 Answers

Neither definition of the notion of aggregate in C++ Standards refers to the destructor.

For example the definition of an aggregate in C++ 20 (9.4.2 Aggregates) sounds the following way

1 An aggregate is an array or a class (Clause 11) with

(1.1) — no user-declared or inherited constructors (11.4.5),

(1.2) — no private or protected direct non-static data members (11.9),

(1.3) — no virtual functions (11.7.3), and

(1.4) — no virtual, private, or protected base classes (11.7.2).

If to execute this statement in MS VS 2019

std::cout << std::is_aggregate_v<B> << '\n';

then the output will be 1.

On the other hand, the default constructor is defined as deleted (the C++ 20 Standard, 11.4.5.2 Default constructors) if

(2.8) — any potentially constructed subobject has a type with a destructor that is deleted or inaccessible from the defaulted default constructor.

But in the provided example there is no such sub-object.

So it seems it is a compiler bug of MS VS 2019.

like image 194
Vlad from Moscow Avatar answered Oct 03 '22 02:10

Vlad from Moscow