Расшаренные ссылки на объекты
Модератор: Модераторы
Расшаренные ссылки на объекты
Относительно недавно на форуме появилась статья, затрагивающая проблемы расшаренных ссылок на объекты и предложенный подход даёт гарантию возбуждения исключения при обращении к невалидной ссылке.
Но вот c++, например, для таких целей с незапамятных времён пользует "умные" указатели(есть правда мнение, что эту идею он невозбранно скоммуниздил из Симулы).
В FPC-3.2.0 тоже вполне можно из говна и палок соорудить нечто подобное, точнее, это можно было аж со времён появления ARC-интерфейсов, но с managed records и генериками это
стало проще и дешевле. Есть и готовые реализации, вроде даже работают.
Интересно любое мнение, насколько это актуально и кто какой подход использует.
PS возможно неправильно выбрал раздел форума.
Но вот c++, например, для таких целей с незапамятных времён пользует "умные" указатели(есть правда мнение, что эту идею он невозбранно скоммуниздил из Симулы).
В FPC-3.2.0 тоже вполне можно из говна и палок соорудить нечто подобное, точнее, это можно было аж со времён появления ARC-интерфейсов, но с managed records и генериками это
стало проще и дешевле. Есть и готовые реализации, вроде даже работают.
Интересно любое мнение, насколько это актуально и кто какой подход использует.
PS возможно неправильно выбрал раздел форума.
использую подход - писать без ошибок управление жизненным циклом объектов, благо это очень просто - ошибки конечно проскальзывают но гдето раз в два - три года. а если использовать тесты то вообще нет проблем.
конечно есть класс задач где владение объектом неопределенно и надо придумывать какиенибудь механизмы, я пару раз спец менеджеры объектов делал с блочным выделением памяти и кешированием освобожденных экземпляров с последующим повторным использованием, но в таких случаях помимо "управления памятью", была кучка другой функциональности которая существенно оправдывала эту работу.
считаю что в паскале надо избавиться от ручного создания освобождения объектов, без каких либо сборщиков мусора конечно и подсчета ссылок, а по нормальному, через анализ кода.
конечно есть класс задач где владение объектом неопределенно и надо придумывать какиенибудь механизмы, я пару раз спец менеджеры объектов делал с блочным выделением памяти и кешированием освобожденных экземпляров с последующим повторным использованием, но в таких случаях помимо "управления памятью", была кучка другой функциональности которая существенно оправдывала эту работу.
считаю что в паскале надо избавиться от ручного создания освобождения объектов, без каких либо сборщиков мусора конечно и подсчета ссылок, а по нормальному, через анализ кода.
sts писал(а):считаю что в паскале надо избавиться от ручного создания освобождения объектов, без каких либо сборщиков мусора конечно и подсчета ссылок, а по нормальному, через анализ кода.
Но это же требует переделки всего компилятора?
а шо делать? на доже как-то развиваться
Это просто скорее всего совершенно нереально для FPC. Кажется, в Rust пошли этим путём?
sts писал(а):а шо делать? на доже как-то развиваться
Подобная тема здесь уже обсуждалась. Проблема даже не в том что нужно переделать компилятор, а в том что нужно еще все библиотеки и существующий на Паскале софт переделать.
Добавлено спустя 1 минуту 18 секунд:
iskander писал(а):Это просто скорее всего совершенно нереально для FPC. Кажется, в Rust пошли этим путём?
Не совсем. Там, фактически, в язык встроен статический анализатор.
>>считаю что в паскале надо избавиться от ручного создания освобождения объектов, без каких либо сборщиков мусора конечно и подсчета ссылок, а по нормальному, через анализ кода.
А я считаю что надо оставить так как есть, прекрасно работает. Для сильно жаждущих автоматики можно добавить в компилятор говна и палок для возможности "нормального" написания умных указателей. а можно и не добавлять))
А я считаю что надо оставить так как есть, прекрасно работает. Для сильно жаждущих автоматики можно добавить в компилятор говна и палок для возможности "нормального" написания умных указателей. а можно и не добавлять))
Интересно любое мнение, насколько это актуально и кто какой подход использует.
Для меня весьма актуально, без умных указателей (и RAII) слишком много лишней работы, которую не хочу делать руками. Через интерфейсы такое делать не вариант -- слишком медленно, проблемы с многопоточности, это подрывает весь смысл указателей. Через Advanced Records и дженерики -- идеальный вариант. Перейду на него, когда перейду на 3.2.0.
А я считаю что надо оставить так как есть, прекрасно работает.
У вас бюджет на отлов AV и утечек памяти бесконечный?
Нет конечно, в хоббийных проектах более менее вылавливаю утечки 1-2 раза в год забесплатно.
Я не думаю что это избавит от ошибок. Хз что лучше АВ при обращении к мусору или забытый кусок памяти сидящий до закрытия прорграммы. первое хоть о себе регулярно напоминает
Я не думаю что это избавит от ошибок. Хз что лучше АВ при обращении к мусору или забытый кусок памяти сидящий до закрытия прорграммы. первое хоть о себе регулярно напоминает
zub писал(а):А я считаю что надо оставить так как есть, прекрасно работает. Для сильно жаждущих автоматики можно добавить в компилятор говна и палок для возможности "нормального" написания умных указателей. а можно и не добавлять))
Так скорее всего и будет оставлено в обозримом будущем, а соответствующие субстанции вроде уже добавили, правда в слегка недоделанном виде.
zub писал(а):Я не думаю что это избавит от ошибок.
Был какой-то опыт в этом смысле?
Я такой компромисс придумал: наследуем все объекты от TInterfacedObject и храним сильные ссылки как пару
Нужно придерживаться правила: после создания объекта сразу же присвоить его парной -Life, и всем остальным, кто хочет продлить жизнь этого объекта, тоже удерживать свою -Life. Преимущество — можно продолжать работать с простой ссылкой на объект, obj, не вводя парных интерфейсов, не работая через поле типа-обёртки и проч.
Для себя в этом варианте я заменил TInterfacedObject на собственную реализацию без интерфейсов (Refcounted) и IInterface на свой managed-тип (Reference). Также конструктор Refcounted принимает life: Reference как var-параметр (логически out, но out генерирует лишний код реинициализации), создаёт объект сразу со счётчиком 1 и присваивает life, что, во-первых, экономит 1 InterlockedIncrement, во-вторых, исключает возможность забыть присвоить Life после создания (но остальные присвоения всё равно остаются на совести пользователя):
Тогда конструкторы наследников, да и любые функции, создающие и возвращающие пользователю объект, тоже должны это делать и передавать в inherited / конструктор:
Код: Выделить всё
var
obj: TMyObject;
objLife: IInterface;
begin
obj := TMyObject.Create; objLife := obj;
...
end;Нужно придерживаться правила: после создания объекта сразу же присвоить его парной -Life, и всем остальным, кто хочет продлить жизнь этого объекта, тоже удерживать свою -Life. Преимущество — можно продолжать работать с простой ссылкой на объект, obj, не вводя парных интерфейсов, не работая через поле типа-обёртки и проч.
Для себя в этом варианте я заменил TInterfacedObject на собственную реализацию без интерфейсов (Refcounted) и IInterface на свой managed-тип (Reference). Также конструктор Refcounted принимает life: Reference как var-параметр (логически out, но out генерирует лишний код реинициализации), создаёт объект сразу со счётчиком 1 и присваивает life, что, во-первых, экономит 1 InterlockedIncrement, во-вторых, исключает возможность забыть присвоить Life после создания (но остальные присвоения всё равно остаются на совести пользователя):
Код: Выделить всё
constructor Refcounted.Create(var life: Reference);
begin
inherited Create;
refcount := 1; life.RawSet(self);
end;Тогда конструкторы наследников, да и любые функции, создающие и возвращающие пользователю объект, тоже должны это делать и передавать в inherited / конструктор:
Код: Выделить всё
type
Child = class(Refcounted)
...
end;
constructor Child.Create(...; var life: Reference);
begin
inherited Create(life);
...
end;>>Был какой-то опыт в этом смысле?
Нет. ошибки никуда не денутся. результат ошибок другой будет
Добавлено спустя 15 минут 53 секунды:
т.к.
>>У вас бюджет на отлов AV и утечек памяти бесконечный?
это удобство написания кода, а не средство уменьшения ошибок
Нет. ошибки никуда не денутся. результат ошибок другой будет
Добавлено спустя 15 минут 53 секунды:
т.к.
>>У вас бюджет на отлов AV и утечек памяти бесконечный?
это удобство написания кода, а не средство уменьшения ошибок
это удобство написания кода, а не средство уменьшения ошибок
Типы и их проверка на этапе компиляции -- тоже удобство для жаждущих, а не средство борьбы с ошибками?
>>Типы и их проверка на этапе компиляции -- тоже удобство для жаждущих, а не средство борьбы с ошибками?
средство
средство
А в чём разница? И то, и то даёт определённые гарантии на этапе компиляции.
