All streams
Search
Write a publication
Pull to refresh
17
0
Send message
кстати safe_ptr не поддерживают указатели на вложенные объекты (например shared_ptr может), это еще одна причина, почему он такой простой. ну и поддержки многопоточности нет, как и у меня.
Люди склонны ошибаться. В любом случае, мы переходим в область субъективных суждений: вряд ли, существует статистика как часто такие ошибки допускают. Могу снова предложить почитать статьи авторов PVS Studio и сделать поправку на то, что им попадает в руки код после ревью, прохождения тестов, а бывает, что и после других анализаторов.

Соглашусь. Rust в этом смысле шаг вперед. Особенно если посмотреть на историю его создания.

И да, всё что делает раст — «встраивает» некоторые проверки в сам язык без необходимости подключать тяжёлую артиллерию в виде статических анализаторов и валгринда (и да, я в курсе, что эти инструменты могут быть полезны и в расте).

Может языку С++ стоит идти в эту же сторону, но с другой стороны — вставлять куски кода помеченные как safe, где будут работать строгие проверки как в Rust. И мы в своем коде будем понемногу расширять область safe: о)
Да. Rust хорош, особенно в воспитательных целях. Вместо преподавателя, по рукам дает компилятор.

Собственно, к чему вообще Rust был упомянут в комментариях: там проблема висячих указателей решается на этапе компиляции (с помощью lifetime).

На что был ответ — не всегда пожно перейти на Rust, поэтому комментарий про Rust вообще не в тему.
да, понял. и not_null и owner хорошо комбинируются с другими указателями.
смотрю на safe_ptr.
да, прям мои мысли, когда я начинал писать свой веловипед. Потом захотелось прикрутить стандартные контейнеры и пришлось всё усложнить. Спасибо за ссылку.

ловить то надо факт лочки мёртвого shared_ptr
гораздо интересенее момент разрушения объекта, на который есть ссылки.

А для релиза достаточно счётчика ссылок и проверки, что при разрушении trackable счётчик равен нулю. Оповещать указатели о том, что объект сдох — бессмысленно.

согласен, но у меня не получилось прикрутить такой простой указатель к стандартным контейнерам. когда на все элементы контейнера один trackable в аллокаторе. Может есть мысли как это можно улучшить?
Спасибо за развернутый комментарий.

это не использовать «голые» указатели в коде вообще.

Так вот нет невладеющих смарт указателей в стандарте (есть попытка observer_ptr).

owner и not_null хороши, но мне кажется not_null это полиси к любому другому указателю, а не отдельный тип.
чтобы можно было иметь owner_not_null, unique_ptr_not_null, shared_ptr_not_null и т.п.

По такому же принципу можно добавить класс scoped_pointer, который будет гарантировать, что любая его копия умрёт раньше, чем указатель, из которого она создана и которым «временно владеет».

очень интересная задачка. есть мысли как можно реализовать эти гарантии? запретить копирование/перемещение?
да… нигде нет счастья: о)
как советуют выше — везде светлая голова нужна
intrusive_ptr вроде не подходит для отлова висячих ссылок.
На самом деле, если не заморачиваться с контейнерами, и перенести чать логики в track::trackable, то можно сделать Track::pointer гораздо эффективнее.
если же вас интересует функциональность, то shared_ptr и weak_ptr обладают нужной функциональностью (по крайней мере я не видел, чтобы кто-то показал обратное)

Как я писал в статье, для отлова ошибок, гораздо интереснее момент, когда разрушается объект, на который есть ссылки, а не когда пытаются обратится по невалидному указателю. В этом случае shared_ptr/weak_ptr никак не помогут.

не значит, что мы не можем использовать shared_ptr/weak_ptr для отлова ошибок в коде

Мы не можем просто взять и добавить в существующий код shared_ptr, потому что если ваши объекты лежат на стеке или в unique_ptr или еще где-то, то нельзя их привязать к shared_ptr.
Вернее можно, указав пустой deleter, но смысла в этом нет. Так как weak_ptr отловят окончание использования shared_ptr'ов, а не разрушение объекта.

Вы предлагаете отлавливать dangling pointers — это это ошибочная ситуация, weak_ptr и shared_ptr позволяют ее отловить и являются стандартным средством языка.

Я как раз думаю иначе.
В стандарте нет средств отлова висячих ссылок, эту проблему хотят частично решать статическим анализом. Мне это не совсем нравится, думаю нужно так же runtime решение. Например такое, как у меня.

Так что сравнение как раз таки имеет смысл.

Ну если очень хочется, давайте сравним.

1. Конструирование объекта: shared_ptr — аллокация; track::trackable — ничего.
2. Создание новоро указателя: shared_ptr — инкремент, track::pointer — четыре присваивания указателей.
3. Удаление указателя: shared_ptr — декремент, track::pointer — четыре присваивания указателей.
4. Удаление объекта: shared_ptr — декремент, weak_ptr — деаллокация; track::pointer — проход по списку указателей с вызовом функции on_dangle.

Вроде так.
Как указали выше или вот тут, некоторые люди, и я в их числе, не считаем, что shared_ptr каким-то образом предназначены для решения проблем висячих ссылок. Могу если надо найти презентацию Герба с табличкой, в которой перечисленны ситуации и указатели, которые нужно при этом использовать.

Так что боюсь само сравнение не имеет смысла.
Скажите как специалист по Rust, как на нем писать ГУИ. Например, по каким-то событиям удалять часть окон и создавать другие?
И смогу ли я в таком случае случайно удалить кнопку, которая сейчас как раз и рассылает событие клик?
С этим трудно спорить — светлая голова лучше тёмной: о).

Но светлая голова не панацея. На любого гения найдется такой сложности проект, который окажется ему не под силу. Здесь главное, какие мы даем инструменты, помогающие ему управлять сложностью или выявлять проблемы как можно раньше.

Все мы крепки задним умом, но иногда система, которую мы программируем ведет себя не так как ожидается. Это нормально, в том смысле, что так было, есть и будет. И здесь при прочих равных на первый план выходит качество и мощь как раз инструментов, которыми обладает программист.

В статье описан, как раз один такой инструмент, со своими достоинствами и недостатками. мне кажется баланс достоинств и недостатков вполне приемлем: о)
С ним другие проблемы, написал об этом в комментарии ниже.

Вообще у любого решения есть проблемы и нюансы, в моем они так же присутствуют. От этого никуда не деться. Вопрос лишь баланса ценности и стоимости того или другого интструмента.
Ловить можно с помощью таких утилит, как MemorySanitizer, valgrind, Dr.Memory и прочих.

Про них я упомянул в статье со списком недостатков, по моему мнению.

И просто взять за правило, что нельзя удалять объект, а потом к нему обращаться.

Это хорошое правило и самоочевидное правило. Так же можно посоветовать соблюдать ПДД чтобы никогда не попадать в аварии. Но мы то знаем, что жизнь сложнее и соблюдение правил не залог безопасности. Снизить вероятность можно, полностью исключить проблем — нельзя.

deleteLater — не GC.

Ну почему же, можно на него посмотреть с этой точки зрения. Вместо удаления объектов, которые нам не нужны, мы помечаем их как неиспользуемые и оставляем в памяти. Ни о каком RAII при этом речь уже идти не может (что также верно и для Java/C#).

Вы точно знаете, когда объект будет удалён — при следующем цикле обработчика событий.

Это половина правды: о). Согласно докам, объект, переданный в deleteLater может быть вообще никогда не удален.

К тому же непонятно что будет если передать туда объект не созданный в куче? Лучше так не делать, это понятно, но как отличить если к вам в функцию пришел указатель на объект и непонятно надо/можно его удалять через deleteLater или нет.

На самом деле я не сильно критикую deleteLater — это хороший инструмент по быстрому исправлению проблем, не более того. Вполне удобное компромиссное решение, по сути костыль, за не имением более достойного варианта.
Эволюция наше всё!
Посоветуйте Линусу слезть с С и переползать на Golang или Rust. Думаю узнаете много идиоматических финских слов: о) (шутка).

В общем-то, поддерживать старые проекты и плавно переводить их на новые плюшки языка — вполне себе выход во многих случаях.

P.S: Эх, где был нынешний bindgen и tokio два года назад...

Вот здесь не уловил.
Тут соглашусь…
после стольких лет топтания на месте язык С++ переживает ренесанс и у многих зачесались ручки добавить в язык кучу «классных» штучек. Меня особо смущает proposal на 2D drawing на основе С библиотеке Cairo.

Но проблема висячих ссылок универсальная, недаром над ней сейчас активно работают и Бьярне и Герб (см. ссылки в статье). Только вот не давать run-time иструмент для решения, а пытаться частично решить с помощью статического анализа, мне кажется в корне не верна. О чем собственно и статья.
Зачем в Rust unsafe?
И как раст помогает в этих случаях?

Там черным по белому написано, что иногда Rust слишком консервативен и не позволит скомпилировать код, не поддающийся валидации.

Дело в том, что в С++ сейчас проблема висячих ссылок попадается тоже очень редко. И нет инструмента по по отлову таких случаев.

Уверен в Rust тоже редко возникают «мутные» места, которые нужно оборачивать в unsafe.
И здесь Rust программисту ничем не помогает.

Information

Rating
Does not participate
Registered
Activity