cpp-ru / ideas

Идеи по улучшению языка C++ для обсуждения
https://cpp-ru.github.io/proposals
Creative Commons Zero v1.0 Universal
89 stars 0 forks source link

Запретить удаление incomplete классов #476

Open sergii-rybin-tfs opened 2 years ago

sergii-rybin-tfs commented 2 years ago

Запретить удаление incomplete классов

Clang & G++ выдают варнинг о UB. Visual Studio компилирует такой код без варнингов.

Само поведение компилятора в этой ситуации ставит в тупик большинство специалистов, и часто является нежелательным (из за утечки памяти и ресурсов в агрегатах). А сама ошибка весьма распространена при попытках реализовать pimpl и подобные паттерны (А так же при изменении порядка инклудов).

Без этой функции, язык будет более предсказуемым и безопасным.

Полезные ссылки:

Пример кода:

class a;
a* val;
void foo()
{
    delete val;
}

class a{
    ~a() = delete;
};
Gargony commented 2 years ago

Можете добавить в полезные ссылки https://stackoverflow.com/questions/4325154/delete-objects-of-incomplete-type

xaizek commented 2 years ago

Совместимость же поломает. В виду этого не хватает анализа того, как часто удаление incomplete классов используется на практике и есть ли от него хоть какая-то польза. Я не могу придумать случая такой необходимости, но возможно это удобно в каких-нибудь кодогенераторах. С другой стороны, кому наплевать на деструктор, всегда может сделать ::operator delete(ptr);. Или, возможно, кому-то важна опциональная возможность вызова деструктора (хотя и для этого можно сделать SFINAE проверку). Думаю proposal должен учитывать эти моменты и описывать, что с ними делать существующему коду.

sergii-rybin-tfs commented 2 years ago

Совместимость же поломает

Если оставить текущее поведение для trivially_destructible классов то будет лишь избавление от UB для всех остальных случаев.

В тоже время, тогда останется поведение, которое дискредитирует RAII паттерн тем, что всегда есть путь для невызова деструктора класса.

xaizek commented 2 years ago

Если оставить текущее поведение для trivially_destructible классов то будет лишь избавление от UB для всех остальных случаев.

Так для определения того, что класс является trivially_destructible, нужно видеть его объявление. Ну и я не про то, что совместимость не надо ломать, а про то, что стоит узнать сколько кода это сломает. К предложению отнесутся более серьёзно, если сказать "успешно собрал кучу кода с -Werror=delete-incomplete" (может есть какой-то простой способ сделать это в nix, например).