Oberon space

General Category => Общий раздел => Тема начата: Губанов Сергей Юрьевич от Март 22, 2012, 09:35:41 am

Название: Минимальная поддержка "умных указателей"
Отправлено: Губанов Сергей Юрьевич от Март 22, 2012, 09:35:41 am
Допустим я реализовал свою "строку". Это структура внутри которой лежит целое число -- как бы "умный указатель". Через это число некий ресурс (в данном случае память под буквы) может быть получен/использован/освобождён.

public struct UnmanagedString
{
    private uint handle;
}

Работать с переменными типа UnmanagedString нужно по особой дисциплине: обычная инструкция копирования "=" для структуры UnmanagedString неприемлема. Для копирования нужно использовать не "=", а специальную процедуру.

Эта специальная процедура в данном случае либо выполнит копирование букв в другой участок памяти и вернёт другой handle, либо, что более оптимально, увеличит количество ссылок на существующую строку. В общем случае эта специальная процедура может сделать чёго-то более трудоёмкое.

Так вот. Возникает вопрос. Что надо минимально потребовать от языка программирования, чтобы программирование "умных указателей" не походило на организацию восхода Солнца вручную. Понятно, что в С++ это сделано далеко не минимально.

Можно было бы потребовать следующее: в языке добавить атрибут структуры означающий, что она некопируемая, а компилятору для таких структур проверять, что для переменных её типа нигде не использована инструкция "=" и они не переданы ни в какую процедуру по значению (только по ссылке). Соответственно, структуры и массивы содержащие некопируемые поля тоже должны быть маркированы атрибутом запрещающим копирование. Это можно было бы сделать, но можно сделать и наоборот...

В последней редакции Оберона-07 вообще никакие структуры не могут быть переданы в процедуру по значению, а только по ссылке. То есть Оберон-07 уже полшага к "умным указателям" сделал. Если действовать в духе Оберона, то лучше будет вообще запретить инструкцию копирования ":=" для любых составных типов. Это дёшево и сердито. Разрешаем применять ":=" только для базовых типов и всё. Копирование объектов составных типов пишем ручками через копирование полей (компилятор легко может это потом соптимизировать, если захочет, так что в рантайме оверхеда не будет).

Оптимум где-то по-середине. Некоторым составным типам копирование всё таки было бы полезно.

Короче, вопрос в следующем. Что разрешить для составных типов по умолчанию: копирование разрешено или запрещено? Если подумать, то очевидно по умолчанию копирование объектов составных типов должно быть запрещено, а разрешать применять к ним инструкцию ":=" программист должен явно (это в каком-то смысле всего лишь оптимизация).
Название: Re: Минимальная поддержка "умных указателей"
Отправлено: DIzer от Март 22, 2012, 10:55:03 am
Не есть гуд -ссылка это ссылка... иногда они создают дополнительный геморрои.. впрочем может ввести аналогично эйфелю  - expanded (развернутые) типы?
Название: Re: Минимальная поддержка "умных указателей"
Отправлено: Губанов Сергей Юрьевич от Март 22, 2012, 11:53:40 am
А разьве expanded не тоже самое что и value? Засунули структуру внутрь объекта и всё.

Для строк это не годится - у них длина переменная.
Название: Re: Минимальная поддержка "умных указателей"
Отправлено: vlad от Март 22, 2012, 07:34:33 pm
Короче, вопрос в следующем. Что разрешить для составных типов по умолчанию: копирование разрешено или запрещено? Если подумать, то очевидно по умолчанию копирование объектов составных типов должно быть запрещено, а разрешать применять к ним инструкцию ":=" программист должен явно (это в каком-то смысле всего лишь оптимизация).

Запрет копирования структур - это такой страшный сон. Наказание за плохое написание циклов :)

На самом деле тебе нужен конструктор и константные мемберы. Это если подходить со стороны "минимизации". Константный мембер "защитит" от дефолтового копирования. Конструктор обеспечит правильную инициализацию этого мембера (через вызов специальной в твоем случае функции копирования). Да, конструктор подразумевает наличие семантики инициализации переменной (этого нет в обероне).

P.S. Хотя все равно не очень понятно как это будет нормально работать без деструкторов. Это неотъемлемая часть "умных указателей" и именно с деструкторами все непросто.
Название: Re: Минимальная поддержка "умных указателей"
Отправлено: Губанов Сергей Юрьевич от Март 23, 2012, 02:43:35 pm
P.S. Хотя все равно не очень понятно как это будет нормально работать без деструкторов. Это неотъемлемая часть "умных указателей" и именно с деструкторами все непросто.
Вот именно. И именно запретом по умолчанию оператора ":=" (в добавок к тому что и так есть в последней редакции Оберона 07) мне видится можно убить большое количество зайцев. Если нет неконтролируемого копирования, значит нет неконтролируемых копий, значит надобность в неявном вызове деструкторов отпадает. А в тех местах где явно/врукопашную скопировал, там же явно/врукопашную и вызвал для этой копии деструктор.

Можно сделать немного по-другому. Например, так: в родном модуле, в котором структура объявлена, для неё оператор ":=" разрешён, а в остальных модулях по умолчанию запрещён.
Название: Re: Минимальная поддержка "умных указателей"
Отправлено: vlad от Март 23, 2012, 05:23:23 pm
Можно сделать немного по-другому. Например, так: в родном модуле, в котором структура объявлена, для неё оператор ":=" разрешён, а в остальных модулях по умолчанию запрещён.

Запрет на копирование мне кажется чересчур жестоким, без смайликов. При этом особого профита все равно не видно - компилятор ничего не контролирует, все делаем ручками.

Мне кажется, что от идеи деструкторов в традиционном ЯП все равно никуда не уйти и она должна быть представлена хоть в каком-то виде. Не надо делать кальку с C++. Пойти непосредственно от идеи: контролируемая (автоматически) инициализация/деинициализация. Контролируемая не только в скопе, но и явная передача контроля вверх/вниз по стеку - это покроет 90% случаев, когда хочется полуавтоматического контроля за ресурсами. И для реализации этой идеи не надо всех тех наворотов, которые есть в С++ (конструкторы копирования, операторы присваивания и т.д.).
Название: Re: Минимальная поддержка "умных указателей"
Отправлено: Губанов Сергей Юрьевич от Март 24, 2012, 02:42:12 pm
Пойти непосредственно от идеи: контролируемая (автоматически) инициализация/деинициализация. Контролируемая не только в скопе, но и явная передача контроля вверх/вниз по стеку - это покроет 90% случаев, когда хочется полуавтоматического контроля за ресурсами.
Я не понял о чём ты.
Название: Re: Минимальная поддержка "умных указателей"
Отправлено: vlad от Март 24, 2012, 03:20:59 pm
Я не понял о чём ты.

Забей :) Когда будет у меня нормальный пропозал - напишу сюда.
Название: Re: Минимальная поддержка "умных указателей"
Отправлено: valexey от Март 26, 2012, 02:15:29 pm
Я тут ковыряю Go (может в принципе по работе пригодиться), возможно вот это будет тут в тему: http://golang.org/doc/go_spec.html#Defer_statements
Название: Re: Минимальная поддержка "умных указателей"
Отправлено: vlad от Март 26, 2012, 03:23:17 pm
Я тут ковыряю Go (может в принципе по работе пригодиться), возможно вот это будет тут в тему: http://golang.org/doc/go_spec.html#Defer_statements

Ну да, это один из возможных "минимальных" подходов. Очень минимальных. Как я понял - он не реюзается. И его нельзя мувать вверх/вниз по стэку.
Название: Re: Минимальная поддержка "умных указателей"
Отправлено: valexey от Март 26, 2012, 03:31:20 pm
Я тут ковыряю Go (может в принципе по работе пригодиться), возможно вот это будет тут в тему: http://golang.org/doc/go_spec.html#Defer_statements

Ну да, это один из возможных "минимальных" подходов. Очень минимальных. Как я понял - он не реюзается. И его нельзя мувать вверх/вниз по стэку.
Вроде бы да, нельзя. А зачем тебе перетасовывать стек?

PS. Если бы подобное было бы в симбиане… Быть может он и не сдох бы. Ибо это сняло бы процентов 60 того BDSM'a c которым приходилось иметь дело разработчику.
Название: Re: Минимальная поддержка "умных указателей"
Отправлено: vlad от Март 26, 2012, 03:43:22 pm
Вроде бы да, нельзя. А зачем тебе перетасовывать стек?

В смысле я хочу вернуть такую штуку из функции. Или передать в функцию. И чтоб оно сделало свою работу (финализирующую) автоматически, гарантировано, и без отвлекания внимания.
Название: Re: Минимальная поддержка "умных указателей"
Отправлено: valexey от Март 26, 2012, 03:53:43 pm
Вроде бы да, нельзя. А зачем тебе перетасовывать стек?

В смысле я хочу вернуть такую штуку из функции. Или передать в функцию. И чтоб оно сделало свою работу (финализирующую) автоматически, гарантировано, и без отвлекания внимания.

ну, это ж statement а не expression. shared_ptr через это не сделать. а вот scoped_ptr - легко.
Название: Re: Минимальная поддержка "умных указателей"
Отправлено: Губанов Сергей Юрьевич от Март 26, 2012, 04:37:28 pm
Я тут ковыряю Go (может в принципе по работе пригодиться), возможно вот это будет тут в тему: http://golang.org/doc/go_spec.html#Defer_statements
Это синтаксический сахар. Он ничего не добавляет по сути.

У меня задача вот какая. Те UnmanagedString о которых я говорил создаются в одном потоке как поля объекта-сообщения, далее этот объект-сообщение обрабатывается в другом потоке и удаляется (фактически помещается в пул для повторного использования). Во время уничтожения все его поля чистятся, соответственно у UnmanagedString вызываются деструктор и она отправляется в свой пул для повторного использования. Так вот мне хочется от языка и от компилятора гарантии, чтобы нигде эта строка никуда не была скопирована простым оператором ":=". Время её жизни равно времени жизни объекта-сообщения и если кто-то её скопирует себе простым оператором ":=", то потом получит сюрприз. Вот поэтому я и думаю о запрете оператора ":=" для некопируемых структур.

Название: Re: Минимальная поддержка "умных указателей"
Отправлено: vlad от Март 26, 2012, 04:47:17 pm
Вот поэтому я и думаю о запрете оператора ":=" для некопируемых структур.

Я так понимаю, что спрятать структуру за указатель нельзя, потому что мы боремся с GC?
Название: Re: Минимальная поддержка "умных указателей"
Отправлено: valexey от Март 26, 2012, 04:53:45 pm
Я тут ковыряю Go (может в принципе по работе пригодиться), возможно вот это будет тут в тему: http://golang.org/doc/go_spec.html#Defer_statements
Это синтаксический сахар. Он ничего не добавляет по сути.
Это действительно не то что тебе нужно, но это и не синтаксический сахар.

У меня задача вот какая. Те UnmanagedString о которых я говорил создаются в одном потоке как поля объекта-сообщения, далее этот объект-сообщение обрабатывается в другом потоке и удаляется (фактически помещается в пул для повторного использования). Во время уничтожения все его поля чистятся, соответственно у UnmanagedString вызываются деструктор и она отправляется в свой пул для повторного использования. Так вот мне хочется от языка и от компилятора гарантии, чтобы нигде эта строка никуда не была скопирована простым оператором ":=". Время её жизни равно времени жизни объекта-сообщения и если кто-то её скопирует себе простым оператором ":=", то потом получит сюрприз. Вот поэтому я и думаю о запрете оператора ":=" для некопируемых структур.
А! Хочется "гермитичности типов"? :-) То есть гарантировать чтобы ни один гад не сохранил "указатель" на сущность которая потом будет "удалена". В общем то умный указатель (типа shared_ptr) тут тебе не поможет, в том плане, что он предотвратит не утекание указателей в левые места, а удаление сущности в случае если они таки утекли. Гарантию в рантайме тут даст только какой-нибудь weak_ptr. Но гарантия в рантайме - это слишком слабая гарантия (IMHO).

Таким образом, умные указатели (как и сборщики мусора) тут совершенно не в тему.

По сути тебе тут для твоих "ссылок" (UnmanagedString) нужно изобрести механизм аналогичный обероновско-виртовской передачи по ссылке записей на стеке (VAR-параметры) и невозможности взять их адрес (получить указатель/ссылку на них в явном виде, которую можно скопировать и так далее).

PS. А в шарпе не бывает opaque типов?
Название: Re: Минимальная поддержка "умных указателей"
Отправлено: Губанов Сергей Юрьевич от Март 26, 2012, 09:40:44 pm
Я так понимаю, что спрятать структуру за указатель нельзя, потому что мы боремся с GC?
Ага. Я написал struct UnmanagedString { private uint handle; } именно для того чтобы не использовать стандартную указательную System.String.

А! Хочется "гермитичности типов"? :-) То есть гарантировать чтобы ни один гад не сохранил "указатель" на сущность которая потом будет "удалена".
Ага.
В общем то умный указатель (типа shared_ptr) тут тебе не поможет, в том плане, что он предотвратит не утекание указателей в левые места, а удаление сущности в случае если они таки утекли.
Меня такой вариант устроит на 100% если "утекание" будет явным (легко найти поиском).
По сути тебе тут для твоих "ссылок" (UnmanagedString) нужно изобрести механизм аналогичный обероновско-виртовской передачи по ссылке записей на стеке (VAR-параметры) и невозможности взять их адрес (получить указатель/ссылку на них в явном виде, которую можно скопировать и так далее).
Да-да-да. Именно об этом я тут и говорю. О невозможности передать UnmanagedString в процедуру не иначе как по ссылке (в Обероне VAR, в C# ref), и о запрете использования для переменных оператора присваивания "=".
PS. А в шарпе не бывает opaque типов?
System.Object, abstract class, interface сойдут?
Название: Re: Минимальная поддержка "умных указателей"
Отправлено: valexey от Март 26, 2012, 09:49:28 pm
По сути тебе тут для твоих "ссылок" (UnmanagedString) нужно изобрести механизм аналогичный обероновско-виртовской передачи по ссылке записей на стеке (VAR-параметры) и невозможности взять их адрес (получить указатель/ссылку на них в явном виде, которую можно скопировать и так далее).
Да-да-да. Именно об этом я тут и говорю. О невозможности передать UnmanagedString в процедуру не иначе как по ссылке (в Обероне VAR, в C# ref), и о запрете использования для переменных оператора присваивания "=".
Ну, если б у меня такая задача возникла бы в джаве, я бы посмотрел в сторону аннотаций (создание своего типа аннотаций) и своей тулзы для их анализа на этапе компиляции (это в джаве делается просто). Насколько я помню, в шарпах всяких есть какой-то аналог этих самых аннотаций. Соответственно тулзень выдавала бы на этапе компиляции ошибку если б какой-то гад попробовал бы утащить куда-то не туда мою преелесть структуру-псевдоссылку.
Название: Re: Минимальная поддержка "умных указателей"
Отправлено: Губанов Сергей Юрьевич от Март 27, 2012, 09:44:35 am
А в Яве уже есть структуры (value-type)?
Название: Re: Минимальная поддержка "умных указателей"
Отправлено: valexey от Март 27, 2012, 09:50:13 am
А в Яве уже есть структуры (value-type)?
Нет. Но рантайм и без них неплохо справляется. На стеке когда нужно размещает. В непрерывный кусок памяти сгребает пачку "структур" (в случае того же массива) и так далее.

Я говорил про то, что если б я не хотел чтобы некая ссылка не уплыла куда не надо, или чтобы запретить в некоторых случаях вызовы некоторых методов у некоторых объектов на этапе компиляции, и мне не хватало бы для этого механизмов инкапсуляции жабы (всякие там public/protected/private/default), я бы использовал аннотации.
Название: Re: Минимальная поддержка "умных указателей"
Отправлено: Губанов Сергей Юрьевич от Апрель 03, 2012, 02:21:53 pm
Пока этот форум был в оффлайне пообсуждали данный вопрос на RSDN:

Приватный operator=
http://rsdn.ru/forum/dotnet/4685453.1.aspx
Название: Re: Минимальная поддержка "умных указателей"
Отправлено: valexey от Апрель 03, 2012, 02:28:47 pm
Пока этот форум был в оффлайне пообсуждали данный вопрос на RSDN:

Приватный operator=
http://rsdn.ru/forum/dotnet/4685453.1.aspx

А ты не смотрел в сторону WeakReferences? (http://msdn.microsoft.com/en-us/library/ms404247.aspx)

По идее при сборке мусора мусорщик не должен на них оглядываться, то есть алгоритм выяснения кто жив а кто нет должен работать независимо от числа слабых ссылок.
Название: Re: Минимальная поддержка "умных указателей"
Отправлено: Губанов Сергей Юрьевич от Апрель 03, 2012, 03:01:02 pm
Ничего полезного в слабых указателях для меня нет.
Название: Re: Минимальная поддержка "умных указателей"
Отправлено: valexey от Апрель 03, 2012, 03:03:06 pm
Ничего полезного в слабых указателях для меня нет.
То есть GC при проверке на живущесть объекта все же пробегается и по всем слабым ссылкам? Если да, это это явный косяк реализации.
Название: Re: Минимальная поддержка "умных указателей"
Отправлено: Губанов Сергей Юрьевич от Апрель 03, 2012, 05:07:26 pm
То есть GC при проверке на живущесть объекта все же пробегается и по всем слабым ссылкам?
Зачем бы ему это делать?

Я говорю что мне они даром не нужны. Применить их не к чему.
Название: Re: Минимальная поддержка "умных указателей"
Отправлено: Valery Solovey от Апрель 03, 2012, 05:55:21 pm
По-моему, наличие слабой ссылки не отменяет указатель. Вроде бы, если указателю на объект присвоить новое значение, то старый объект считается мусором: слабые ссылки-то не обходятся... А значит, в один прекрасный момент мусор будет собран, и слабые указатели как минимум перестанут указывать на объект.
Название: Re: Минимальная поддержка "умных указателей"
Отправлено: valexey от Апрель 03, 2012, 06:17:52 pm
По-моему, наличие слабой ссылки не отменяет указатель. Вроде бы, если указателю на объект присвоить новое значение, то старый объект считается мусором: слабые ссылки-то не обходятся... А значит, в один прекрасный момент мусор будет собран, и слабые указатели как минимум перестанут указывать на объект.
Именно в этом и их смысл - если сильных ссылок не осталось, объект стал мусорным и слабые ссылки становятся не валидными. (в некоторых релизациях они обнуляются)