ideas icon indicating copy to clipboard operation
ideas copied to clipboard

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

Open sergii-rybin-tfs opened this issue 4 years ago • 4 comments

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

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

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

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

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

  • https://en.cppreference.com/w/cpp/language/delete
  • https://godbolt.org/z/xKeG3Y1xb
  • https://stackoverflow.com/questions/4325154/delete-objects-of-incomplete-type
  • https://wiki.sei.cmu.edu/confluence/display/cplusplus/EXP57-CPP.+Do+not+cast+or+delete+pointers+to+incomplete+classes

Пример кода:

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

class a{
    ~a() = delete;
};

sergii-rybin-tfs avatar Aug 24 '21 14:08 sergii-rybin-tfs

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

Gargony avatar Aug 25 '21 03:08 Gargony

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

xaizek avatar Aug 28 '21 12:08 xaizek

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

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

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

sergii-rybin-tfs avatar Dec 26 '21 09:12 sergii-rybin-tfs

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

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

xaizek avatar Dec 26 '21 12:12 xaizek