Давайте рассмотрим этот класс:
class A {
public:
A() = delete;
A(int i) :
i_m(i) {
std::cout << __PRETTY_FUNCTION__ << ' ' << i_m << '\n';
}
~A() {
std::cout << __PRETTY_FUNCTION__ << ' ' << i_m << '\n';
}
private:
int i_m{1234567890};
};
Конструктор по умолчанию явно удален, поэтому AFAIK A
может быть построен только из целого числа. Инициализация по умолчанию для элемента данных i_m
никогда не будет использоваться.
Давайте рассмотрим эту программу:
int main() {
using T = std::array<A, 2>;
//T a;
// error: use of deleted function 'std::array<A, 2>::array()'
// note: 'std::array<A, 2>::array()' is implicitly deleted because the default definition would be ill-formed
// error: use of deleted function 'A::A()'
//T b{};
// error: use of deleted function 'A::A()'
}
Опять же, мне это кажется вполне подходящим.
Давайте теперь рассмотрим эту другую программу:
int main() {
using T = std::array<A, 2>;
auto foo = new T{};
delete foo;
auto foo_init = new T{1, 2};
delete foo_init;
// auto zorg = new T();
// delete zorg;
// error: use of deleted function 'std::array<A, 2>::array()'
// note: 'std::array<A, 2>::array()' is implicitly deleted because the default definition would be ill-formed:
// error: use of deleted function 'A::A()'
auto zorg_init = new T({3, 4});
delete zorg_init;
}
Этот код выполняет компиляцию (без предупреждения) и генерирует следующий вывод:
A::~A() 0
A::~A() 38870160
A::A(int) 1
A::A(int) 2
A::~A() 2
A::~A() 1
A::A(int) 3
A::A(int) 4
A::~A() 4
A::~A() 3
А теперь что-то мне кажется не хорошо. Как это возможно, что линия auto foo = new T{};
не считается неправильной? Инициализация класса A
здесь полностью обойдена.
Ничего не стоит, если этот код не компилируется:
int main() {
auto p = new A{};
delete p;
}
Ожидаемая ошибка:
error: use of deleted function 'A::A()'
Я тестировал эти коды со следующими параметрами: -Wall -Wextra -pedantic -std=c++17
. gcc -v
дает: gcc version 7.2.0 (x86_64-posix-sjlj-rev0, Built by MinGW-W64 project)
на моем компьютере.
Любое объяснение будет с благодарностью:)
PS: после исчерпывающих тестов в Compiler Explorer (используется с примером ) https://godbolt.org/z/5VZLU_), похоже, это проблема в g cc 7.x. Действительно, только 7.x версии g cc компилируют этот пример. г cc 6,4 нет. г cc 8,1 нет. ни лязгать ни msv c none.
Можете ли вы подтвердить, что здесь нет UB и это действительно ошибка компилятора?