GlebZ,
> Что-то я торможу, вы хотите сказать что программа вида: >
> void C::test()
> {
> A a=new gcnew A();
> int% b = a.a();
> a=null;
> GC::Collect();
> b = 15;
> }
>
Да. Если чуть-чуть подправить:
void C::test()
{
A^ a = gcnew A();
int% b = a->a();
a = nullptr;
GC::Collect();
b = 15;
}
то преспокойненько компилируется (/clr:safe) и исполняется. Согласно спецификации CLI, managed pointers не могут быть null. Соответственно, GC не будет удалять созданный объект, пока есть managed pointer, указывающий на него.
Posted via RSDN NNTP Server 2.0 alpha
Легче одурачить людей, чем убедить их в том, что они одурачены. — Марк Твен
Здравствуйте, Павел Кузнецов, Вы писали:
ПК>то преспокойненько компилируется (/clr:safe) и исполняется. Согласно спецификации CLI, managed pointers не могут быть null. Соответственно, GC не будет удалять созданный объект, пока есть managed pointer, указывающий на него.
Это не указатели. Это карты доступности объеков.
... << RSDN@Home 1.1.4 beta 3 rev. 279>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, Serginio1, Вы писали: S>>Плохо тем, что это не верифицируется. Потому, что нет способа убедиться, что ты вернул из пользовательского кода не просто управляемый указатель, а управляемый указатель на валидный объект. К сожалению, инструкции ldarga и ldloca портят всю картину. S> Ну дык возврат стековой переменной должен быть пресечен уже на этапе компиляции. Или я не о том.
Ты не о том. Не важно, что там делает компилятор. В C# тебе синтаксис вообще не позволит даже декларировать такой метод. S> Что в данном случае верификация????
Гм. Есть формально определенный процесс верификации CIL-кода. Грубо говоря, ты не можешь загрузить сборку, в которой лежит код, не проходящий верификацию. И эта верификация ломается, как только ты пытаешься объявить метод возвращающим ссылку. Хотя ты можешь породить такой код — нестандартным компилятором, руками, или ilasm-ом.
S>>На самом деле, для кулдевелоперов есть-таки лазейка. Можно локализовать такой код в сборке, которой выдается привилегия игнорировать верификацию.
... << RSDN@Home 1.1.4 beta 4 rev. 303>>
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Здравствуйте, VladD2, Вы писали: VD>Делать ссылки можно только в стэке. Так что как раз ссылочный индекс (хоть это и бессмысленно) как раз сделать можно.
Это небессмысленно. Это невозможно — верификатор не пропустит такой код. VD>А вот сделать поле-ссылку нельзя. И это уже системное ограничение реализации ЖЦ в дотнете.
... << RSDN@Home 1.1.4 beta 4 rev. 303>>
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Здравствуйте, VladD2, Вы писали:
VD>Так вот поколения меняются, а адрес нет.
VD>В общем, химиячут что-то гады. Или отлачик фигню показывает.
Здесь интересен сам механизм.
Так для фиксированных объектов GC запрещает их перемещение, но при этом есть область этой фиксации, в том числе и передаваемых по ссылке значением.
Другая ситуация с возвращаемым по ссылке значениям. В данном случае ссылка сама должна следить за фиксацией объекта а значит и иметь информацию о нем.
В твоем коде все достаточно прозрачно и компилятор сам может все разрулить и проинлайнить.
Другое дело если возвращать не поле о объявляемого объекта а например по третьей точке.
... << RSDN@Home 1.1.4 beta 4 rev. 303>>
и солнце б утром не вставало, когда бы не было меня
Здравствуйте, Sinclair, Вы писали:
S>> Что в данном случае верификация???? S>Гм. Есть формально определенный процесс верификации CIL-кода. Грубо говоря, ты не можешь загрузить сборку, в которой лежит код, не проходящий верификацию. И эта верификация ломается, как только ты пытаешься объявить метод возвращающим ссылку. Хотя ты можешь породить такой код — нестандартным компилятором, руками, или ilasm-ом.
Как то баловался с Delphi.Net с указателями. Так вот в Delphi небыло fixed при этом передавалась неотпинненый указатель.
Так вот если все происходило в одном методе все прекрасно как только данный указатель передовался в другую процедуру приложение просто падало. При этом с этим указателем совершались адресная арифметика.
... << RSDN@Home 1.1.4 beta 4 rev. 303>>
и солнце б утром не вставало, когда бы не было меня
Здравствуйте, Serginio1, Вы писали:
S> Так для фиксированных объектов GC запрещает их перемещение, но при этом есть область этой фиксации, в том числе и передаваемых по ссылке значением.
Ничего он запрещать не должен. Ссылка есть ссылка. Просто если она не на начало объекта, то у ЖЦ прибаляется работы. Он должен хранить информацию, что в таких-то ячейках могут быть ссылки и какого типа эти ссыли, и в придачу, хранить отступ этой самой ссылки от начала объекта. Далее года объекты перемещаются нужно всего лишь корректировать указатели с учетом этих отступов.
Отсюда, кстати, и вытекает невозможность размещения ссылок в других объектах. Иначе неясно как и где хранить информацию об отступе.
S> Другая ситуация с возвращаемым по ссылке значениям. В данном случае ссылка сама должна следить за фиксацией объекта а значит и иметь информацию о нем.
Нет там никаких фиксаций. Ну, по крайней мере не должно быть. К тому же ЖЦ четко показывает, что объекты между поколениями перемещаются, а в связи с внутренним устройсвом перемещение объектов между поколением обязано приводить к перемещению объектов в другие области памяти. Таким образом скорее всего врет отладчик. Адрес рельно меняется, но отладчик просто показывает старый ардес.
S> В твоем коде все достаточно прозрачно и компилятор сам может все разрулить и проинлайнить.
Инлайн тут не причем.
S> Другое дело если возвращать не поле о объявляемого объекта а например по третьей точке.
Об это и речь. Иначе бы это было вообще обычное поведение ЖЦ и о ссылках говорить было бы бессмысленно.
Кстати, TypedReference делает почти тоже самое. Просто в мсил вставляется дополнительная информация, а сам объект исчезает.
Кстати, я тут проверил... возврат ссылки из функции — это не верефицируемая операция и стало быть то, что код с возвратом ссылок компилируется в сэйф-режиме просто на просто баг компилятора.
Чтобы проверить свое предположения я скормил сборку PEVerify.exe:
d:\MyProjects\Tests\CppAsm\debug>d:\VS2005\SDK\v2.0\Bin\PEVerify.exe CppAsm.dll
Microsoft (R) .NET Framework PE Verifier. Version 2.0.41115.19
Copyright (C) Microsoft Corporation. All rights reserved.
d:\myprojects\tests\cppasm\cppasm\cppasm.h(34) : [IL]: Error: [d:\MyProjects\Tes
ts\CppAsm\debug\CppAsm.dll : CppAsm.A::get][offset 0x0000000C] Return type is BY
REF, TypedReference, ArgHandle, or ArgIterator.
d:\myprojects\tests\cppasm\cppasm\cppasm.h(38) : [IL]: Error: [d:\MyProjects\Tes
ts\CppAsm\debug\CppAsm.dll : CppAsm.A::get_Item][offset 0x0000000C] Return type
is BYREF, TypedReference, ArgHandle, or ArgIterator.
2 Errors Verifying CppAsm.dll
Короче все это мало чем отличается от работы с указателями в ансэйфе Шарпа.
... << RSDN@Home 1.1.4 beta 3 rev. 279>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
VladD2,
> Кстати, я тут проверил... возврат ссылки из функции — это не верефицируемая операция
Неверифицируемая стандартным алгоритмом, описанным в спецификации CLI. Но это не означает, что эта операция неверифицируема реализацией Microsoft. В частности, чтобы это проверить, нужно пользоваться не утилитой PEVerify, проверяющей код на верифицируемость стандартным алгоритмом, а попробовать использовать подобную сборку в контексте, где разрешен запуск только верифицируемого кода.
> и стало быть то, что код с возвратом ссылок компилируется в сэйф-режиме просто на просто баг компилятора.
Конкретная реализация (например, Microsoft CLR) вполне может
большее количество случаев, как прямо оговарено спецификацией.
The implementation might also run other programs provided it is able to show they do not violate memory safety (typically because they use a verification algorithm that makes use of specific knowledge about the implementation).
[Note: While a compliant implementation is required to accept and run any program this verification algorithm states is verifiable, there might be programs that are accepted as verifiable by a given implementation but which this verification algorithm will fail to consider verifiable. Such programs will run in the given implementation but need not be considered verifiable by other implementations.
For example, an implementation of the CLI might choose to correctly track full signatures on method pointers and permit programs to execute the calli instruction even though this is not permitted by the verification algorithm specified here.
Implementers of the CLI are urged to provide a means for testing whether programs generated on their implementation meet this portable verifiability standard. They are also urged to specify where their verification algorithms are more permissive than this standard. end note]
> Чтобы проверить свое предположения я скормил сборку PEVerify.exe:
Эта утилита, в соответствии с пожеланием спецификации CLI, процитированным выше, проверяет верифицируемость стандартным алгоритмом.
Implementation Specific (Microsoft)
The various implementations of the CLI produced by Microsoft use slightly different verification algorithms. In all cases, however, the PEVerify program (part of the SDK) implements the portable verification algorithm as specified in this Standard. Programmers are urged to run PEVerify over all code before shipping it for possible use on other implementations of the CLI.
> Короче все это мало чем отличается от работы с указателями в ансэйфе Шарпа.
Отличается: с точки зрения реализации Microsoft сам по себе возврат unmanaged pointers, судя по всему, не приводит к тому, что код перестает быть верифицируемым.
Posted via RSDN NNTP Server 2.0 alpha
Легче одурачить людей, чем убедить их в том, что они одурачены. — Марк Твен
Здравствуйте, Павел Кузнецов, Вы писали:
ПК>О! Так это не оговорка, а заблуждение Смотри сюда:
Тут я вразился не очень корректно. Конечно это не одно и тоже в буквальном смысле. Но TypedReference именно что использует менеджед-ссылку внутри себя плюс добавляет поле описывающее тип объекта на который указывает ссылка.
Жаль только, что TypedReference даже в ансэфе нельзя возвратить из функции.
Что касается того, что МС++ — это компилирует в сэйф-режиме, так это глюк. Тут я подробно об этом написал: Re[24]: C# — необходимость?
VladD2,
> Что касается того, что МС++ — это компилирует в сэйф-режиме, так это глюк. Тут я подробно об этом написал: > Re[24]: C# — необходимость?
Здравствуйте, Serginio1, Вы писали:
S> Как то баловался с Delphi.Net с указателями. Так вот в Delphi небыло fixed при этом передавалась неотпинненый указатель. S> Так вот если все происходило в одном методе все прекрасно как только данный указатель передовался в другую процедуру приложение просто падало. При этом с этим указателем совершались адресная арифметика.
Указатели разные бывают. Бывают управляемые, а бывают нет. Кстат, ссылки все же отличаются от указателей. Сссылки в качестве параметров — это вполне безопасная операция. Небозопасной она становится при возврате из функции или помещении в тело объекта.
... << RSDN@Home 1.1.4 beta 3 rev. 279>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Твоя самоуверенность меня просто удивляет... Нет, чтобы разобраться, как следует (например, попробовать использовать полученную сборку в соответствующем контексте), продолжаешь упорствовать на ровном месте.
> Лучше сообще орлам что компилятор делают. Думаю, они знаю что делать.
Чтобы убедиться в том, что это сознательно добавленная возможность, а не ошибка, лучше попробуй вернуть в режиме /clr:safe, например, ссылку на локальную переменную, а потом почитай справку о возникшей ошибке:
error C4801: Return by reference is not verifiable: gc-lvalue is from an unknown source
<...> A reference can only be verifiably returned when it can be tracked by the verifier from creation to return point and when it is a reference to an element of an array, or a member of a class. <...>
Posted via RSDN NNTP Server 2.0 alpha
Легче одурачить людей, чем убедить их в том, что они одурачены. — Марк Твен