Здравствуйте!
Я, конечно, еще только начинающий специалист в программировании на С++, но меня, однако, удивляет тот факт, что в новом 11 стандарте внесены рад изменений, вызывающих оживленные споры (как и все новое). Но возьмем конкретный пример с выделением и освобождением памяти:
class A
{
int *p;
A::A()
{
p = new int;
}
A::~A()
{
if (p) delete p;
}
void set()
{
if (p) delete p;
p = new int;
}
void unset()
{
if (p) delete p;
//p = NULL; // without this the program is received SIGSEGV
}
};
int main()
{
A a;
a.set();
a.unset();
return 0;
}
Мы создаем объект класса и выделяем память полю класса методом set().
Затем, в некоторый момент времени мы освобождаем память методом unset().
При вызове деструктора если явно не обнулить указатель, он будет удален дважды и программа упадет.
Почему же в новом стандарте среди прочих изменений не добавили обнуление указателя оператором delete ?
Если кто-то считает, что автоматическое обнуление указателя здесь неуместно, пожалуйста, приведите пример, где нам может понадобиться значение указателя после его освобождения — я с такой ситуацией не сталкивался.
16.04.12 19:10: Перенесено модератором из 'C/C++. Прикладные вопросы' — Кодт
Whoa...I did a 'zcat /vmlinuz > /dev/audio' and I think I heard God...
H>Я, конечно, еще только начинающий специалист в программировании на С++, но меня, однако, удивляет тот факт, что в новом 11 стандарте внесены рад изменений, вызывающих оживленные споры (как и все новое).
какие? в студию
H>Почему же в новом стандарте среди прочих изменений не добавили обнуление указателя оператором delete ?
зачем? каждый оператор выполняет только свою функцию. так же, С++ не контролирует и не будет контролировать тупость программиста
Здравствуйте, о_О, Вы писали:
H>>Почему же в новом стандарте среди прочих изменений не добавили обнуление указателя оператором delete ? о_О>зачем? каждый оператор выполняет только свою функцию. так же, С++ не контролирует и не будет контролировать тупость программиста
Статическую типизацию тоже надо отменить, чтобы не контролировать тупость программиста.
...
H>Почему же в новом стандарте среди прочих изменений не добавили обнуление указателя оператором delete ?
Чтобы что-то обнулять, это что-то должно быть l-value. Это избыточное требование как с точки зрения написания исходного кода, так и с точки зрения генерации машинного кода.
Пример с set/unset дурацкий. Здесь умные указатели в любом отношении лучше подходят.
Думаю, все из вас описывали цикл для обработки данных, в начале которого стояла инициализация параметров новыми значениями с выделением памяти, над которыми в теле цикла производились вычисления, а в конце цикла производилась очистка параметров и освобождение памяти. Зачастую нам приходится получать указатели из внешних библиотек, которые мы затем должны сами освободить. Так что какого рода указатели использовать — это уже решать по контексту задачи.
Что же касается причин необнуления указателя оператором delete, так это то, что он указатель принимает по значению и фактически не может обнулить его. Остальные доводы неубедительные и носят , скорее всего, идеологически-политический характер
Whoa...I did a 'zcat /vmlinuz > /dev/audio' and I think I heard God...
Здравствуйте, Handler, Вы писали:
H>Думаю, все из вас описывали цикл для обработки данных, в начале которого стояла инициализация параметров новыми значениями с выделением памяти, над которыми в теле цикла производились вычисления, а в конце цикла производилась очистка параметров и освобождение памяти. Зачастую нам приходится получать указатели из внешних библиотек, которые мы затем должны сами освободить. Так что какого рода
указатели использовать — это уже решать по контексту задачи.
Ну дык умные указатели тебе в помощь. Или напиши свой
template<class T> void DeleteAndNil(T &*p) { delete p; p = 0; }
Кстати, в случае наличия исключений, поддержка кода без умных указателей становится очень нетривиальной.
Здравствуйте, Handler, Вы писали:
H>Думаю, все из вас описывали цикл для обработки данных, в начале которого стояла инициализация параметров новыми значениями с выделением памяти, над которыми в теле цикла производились вычисления, а в конце цикла производилась очистка параметров и освобождение памяти. Зачастую нам приходится получать указатели из внешних библиотек, которые мы затем должны сами освободить. Так что какого рода указатели использовать — это уже решать по контексту задачи. H>Что же касается причин необнуления указателя оператором delete, так это то, что он указатель принимает по значению и фактически не может обнулить его. Остальные доводы неубедительные и носят , скорее всего, идеологически-политический характер
В настоящее время, в С++ не используют operator delete. Точка.
Если вы пишете "delete" (кроме =delete), значит вы пишете на каком-то другом языке, не на С++. Например на "С с какими-то фичами из С++".
Обычно используют std::unique_ptr. Работа с внешними либами — через reset/release/свой deleter.
Здравствуйте, Abyx, Вы писали:
A>В настоящее время, в С++ не используют operator delete. Точка. A>Если вы пишете "delete" (кроме =delete), значит вы пишете на каком-то другом языке, не на С++. Например на "С с какими-то фичами из С++".
Здравствуйте, Handler, Вы писали: H>Почему же в новом стандарте среди прочих изменений не добавили обнуление указателя оператором delete ?
да хотя бы потому что указателя может быть два на одну и ту же область
Здравствуйте, Евгений Музыченко, Вы писали:
ЕМ>Здравствуйте, Abyx, Вы писали:
A>>В настоящее время, в С++ не используют operator delete. Точка. A>>Если вы пишете "delete" (кроме =delete), значит вы пишете на каком-то другом языке, не на С++. Например на "С с какими-то фичами из С++".
ЕМ>Это Вы сами придумали, или подсказал кто?
Нет. Это придумал не я.
Почитайте Elements of Modern C++ Style Саттера, посмотрите GoingNative2012, другие статьи\доклады на последние полгода.
Конкретно про указатели, есть замечательная презентация by Konrad Rudolph — http://tinyurl.com/fuck-pointers
Здравствуйте, Abyx, Вы писали:
A>Почитайте Elements of Modern C++ Style Саттера, посмотрите GoingNative2012, другие статьи\доклады на последние полгода.
Угу. Это означает, что некоторая группа людей, активно выступающая на публике, считает использование указателей неправильным. И не более того. Точно так же, как группа людей, называющих себя "православными" очень любит говорить "от лица всей русской нации", не имея не то никаких оснований. Так что Ваше "не используют, и точка" — это пальтсы в чистом виде.
> Нет. Это придумал не я. > Почитайте Elements of Modern C++ Style Саттера, посмотрите GoingNative2012, > другие статьи\доклады на последние полгода.
Читать конечно полезно, но знаешь, свою голову на плечах иногда напрягать тоже
не мешает (тебе, я имею в виду). Я конечно всё понимаю, в смысле, что ты имел
в виду, когда писал свой пост, но вот так вот сказать, что я уж совсем нигде
не допускал применение delete я не могу, т.н. "современный С++" настолько
разнообразен, везде свои требования и особенности.
Здравствуйте, Евгений Музыченко, Вы писали:
ЕМ>Здравствуйте, Abyx, Вы писали:
A>>Почитайте Elements of Modern C++ Style Саттера, посмотрите GoingNative2012, другие статьи\доклады на последние полгода.
ЕМ>Угу. Это означает, что некоторая группа людей, активно выступающая на публике, считает использование указателей неправильным. И не более того. Точно так же, как группа людей, называющих себя "православными" очень любит говорить "от лица всей русской нации", не имея не то никаких оснований. Так что Ваше "не используют, и точка" — это пальтсы в чистом виде.
Всё правильно. Есть разные группы людей.
Например, очень большая группа людей, которые любят писать Сишный код в .cpp файлах.
Есть другие группы людей, которые застряли в прошлом, и не обращают внимания на то, прогресс ушел вперед.
И есть группы людей, которые представляют настоящее.
Однако тут дело не в том, что какая-то группа людей что-то навыдумывала и говорит за всех остальных.
Фраза "В С++ operator delete не нужен" — это констатация факта.
С сентября 2011, "С++" стал означать "язык, соответствующий ISO/IEC 14882:2011".
В нем есть некопируемый, exception-safe, легковесный unique_ptr.
Он позволяет заменить потенциально опасный код `foo(); delete p; }` на безопасный код `foo(); }`, без каких-либо потерь.
*Мы* пишем надежный код, по этому мы больше не можем использовать опасный delete вместо безопасного RAII.
(*Мы* — это некоторая группа людей, к которой я себя отношу)
Если вы пишете на С++03, то с сентября 2011 вы больше не пишете на "С++" (или, на "современном С++", или на "реализации С++, соответствующей действующему стандарту С++").
Еще раз, фраза "В С++ operator delete не нужен" — относится только к версии стандарта С++, действующей на данный момент, а не к устревшим версиям стандарта.
>> Нет. Это придумал не я. >> Почитайте Elements of Modern C++ Style Саттера, посмотрите GoingNative2012, >> другие статьи\доклады на последние полгода.
MZ>Читать конечно полезно, но знаешь, свою голову на плечах иногда напрягать тоже MZ>не мешает (тебе, я имею в виду). Я конечно всё понимаю, в смысле, что ты имел MZ>в виду, когда писал свой пост, но вот так вот сказать, что я уж совсем нигде MZ>не допускал применение delete я не могу, т.н. "современный С++" настолько MZ>разнообразен, везде свои требования и особенности.
Я не могу придумать хорошего примера, где нужно было бы использовать delete.
Разумеется, при написании библиотечного класса типа ptr_vector, delete будет уместен.
Однако к библиотечному коду применяются несколько другие требования, реализацию можно писать и не на "С++, а на "С с классами".
Если библиотечный код небольшой, на 100% покрыт юнит-тестами, никогда не изменяется после написания, то на небезопастность delete можно не обращать внимания,
тут скорее будет важен факт, что unique_ptr<T> в заголовке добавит лишние секунды ко времени копиляции большого проекта.
Однако, для качественного пользовательского кода, который сложен, часто меняется разными людьми, плохо покрыт автоматическми тестами, я не вижу ситуации когда следовало бы использовать delete вместо той или обертки над указателями.
> Разумеется, при написании библиотечного класса типа ptr_vector, delete будет > уместен. > Однако к библиотечному коду применяются несколько другие требования, реализацию > можно писать и не на "С++, а на "С с классами".
Ты не пишешь библиотечный код ?
> Если библиотечный код небольшой, на 100% покрыт юнит-тестами, никогда не > изменяется после написания, то на небезопастность delete можно не обращать внимания, > тут скорее будет важен факт, что unique_ptr<T> в заголовке добавит лишние > секунды ко времени копиляции большого проекта.
У меня тупо может не быть unique_ptr<T> в распоряжении.
Здравствуйте, MasterZiv, Вы писали:
>> Если библиотечный код небольшой, на 100% покрыт юнит-тестами, никогда не >> изменяется после написания, то на небезопастность delete можно не обращать внимания, >> тут скорее будет важен факт, что unique_ptr<T> в заголовке добавит лишние >> секунды ко времени копиляции большого проекта.
MZ>У меня тупо может не быть unique_ptr<T> в распоряжении.
Здравствуйте, Abyx, Вы писали:
A>Есть другие группы людей, которые застряли в прошлом, и не обращают внимания на то, прогресс ушел вперед.
Да-да-да. Безусловно, застряли в прошлом все, кто еще не сменил XP на Win7, iPhone3 на iPhone4, автомобиль на последнюю модель, и так далее. Знакомо.
A>Фраза "В С++ operator delete не нужен" — это констатация факта.
О, Вы уже слегка переделали фразу, теперь она выглядит несколько более вменяемо, нежели в оригинале. Глядишь, так потихоньку и убеждения станут более адекватными.
A>С сентября 2011, "С++" стал означать "язык, соответствующий ISO/IEC 14882:2011".
Это Ваши сугубо личные фантазии. "C++" как означало, так и означает "язык, соответствующий одной из реализаций стандартов C++, официальных или неофициальных". Увы и ах. А вот "C++11" действительно означает "C++, соответствующий ISO/IEC 14882:2011".
A>В нем есть некопируемый, exception-safe, легковесный unique_ptr. A>Он позволяет заменить потенциально опасный код `foo(); delete p; }` на безопасный код `foo();
Безопасного кода, как Вы сами должны понимать, от простой замены не образуется. Код всего лишь становится потенциально менее опасным, только и всего.
A>*Мы* пишем надежный код, по этому мы больше не можем использовать опасный delete вместо безопасного RAII.
Вам очень пойдет нести какой-нибудь транспарант на демонстрации.
A>Если вы пишете на С++03, то с сентября 2011 вы больше не пишете на "С++"
false
A> (или, на "современном С++",
false
A> или на "реализации С++, соответствующей действующему стандарту С++").
true
Видите ли, "бьют не по паспорту, а по морде". До того, как реализации C++11 станут реально массовыми и будут достаточно вылизаны, пройдет минимум несколько лет. Вот тогда пафос, который Вы демонстрируете сейчас, станет сколько-нибудь оправданным.
Здравствуйте, Евгений Музыченко, Вы писали:
ЕМ>Видите ли, "бьют не по паспорту, а по морде". До того, как реализации C++11 станут реально массовыми и будут достаточно вылизаны, пройдет минимум несколько лет.
VC++10 уже два года как есть,
g++ с unique_ptr (хз в какой версии появилось) сейчас наверное уже во всех никсах
Здравствуйте, Abyx, Вы писали:
A>>>В настоящее время, в С++ не используют operator delete. Точка. A>>>Если вы пишете "delete" (кроме =delete), значит вы пишете на каком-то другом языке, не на С++. Например на "С с какими-то фичами из С++".
ЕМ>>Это Вы сами придумали, или подсказал кто?
A>Нет. Это придумал не я. A>Почитайте Elements of Modern C++ Style Саттера, посмотрите GoingNative2012, другие статьи\доклады на последние полгода. A>Конкретно про указатели, есть замечательная презентация by Konrad Rudolph — http://tinyurl.com/fuck-pointers
Это правильные книги и публикации, в них сказаны правильные вещи и писали их правильные люди. Только, судя по всему, понял ты их не совсем правильно — рекомендации принял как догмы. Там сказано: старайтесь активно использовать, где только можно, идиому RAII, умные указатели, стандартные контейнеры и т.п. А ты это понял так: "забудьте о существовании указателей, даже не помышляйте о создании собственных контейнеров, умных указателей и менеджеров памяти, а операторы new и delete даже обсуждать не смейте".
--
Не можешь достичь желаемого — пожелай достигнутого.
Здравствуйте, rg45, Вы писали:
R>Это правильные книги и публикации, в них сказаны правильные вещи и писали их правильные люди. Только, судя по всему, понял ты их не совсем правильно — рекомендации принял как догмы. Там сказано: старайтесь активно использовать, где только можно, идиому RAII, умные указатели, стандартные контейнеры и т.п. А ты это понял так: "забудьте о существовании указателей, даже не помышляйте о создании собственных контейнеров, умных указателей и менеджеров памяти, а операторы new и delete даже обсуждать не смейте".
"ты .. понял"
научите меня телепатии, я тоже так хочу