Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Прочее";
Текущий архив: 2011.03.20;
Скачать: [xml.tar.bz2];

Вниз

Высокий/низкий уровень, ручное/автоматическое управление   Найти похожие ветки 

 
DiamondShark ©   (2010-12-03 18:02) [400]


> oxffff ©   (03.12.10 08:53) [399]

ILdasm откроет истину.


 
_oxffff   (2010-12-04 00:31) [401]


> DiamondShark ©   (03.12.10 18:02) [400]
>
> > oxffff ©   (03.12.10 08:53) [399]
>
> ILdasm откроет истину


Ildasm не откроет истину.
А только отладчик нативного кода поможет.

Действительно при вызове через boxed объект внутри происходит подстройка смещения на начало содержимого(это хорошо видно на присвоении a = 5). Появляется префикс constrained в MSIL для tostring и каждый такой вызов создает еще по экземпляру, но кто об этом знает. Результат ожидаем поскольку

When callvirt method instruction has been prefixed by constrained thisType the instruction is executed as follows.
If thisType is a reference type (as opposed to a value type) then
ptr is dereferenced and passed as the ‘this’ pointer to the callvirt of method
If thisType is a value type and thisType implements method then
ptr is passed unmodified as the ‘this’ pointer to a call of method implemented by thisType  
If thisType is a value type and thisType does not implement method then
ptr is dereferenced, boxed, and passed as the ‘this’ pointer to the callvirt of method
This last case can only occur when method was defined on System.Object, System.ValueType, or System.Enum and not overridden by thisType.   In this last case, the boxing causes a copy of the original object to be made, however since all methods on System.Object, System.ValueType, and System.Enum do not modify the state of the object, this fact can not be detected.  

Очень рекомендую к просмотру под отладчиком VS  в go to Disassembly режиме, а также посмотреть на состояние управляемой кучи. Новые объекты создаются рядом друг за другом. Интересно.  

   class Program
   {
       interface IMyInt
       {
           int func(object obj);
       };
       interface IMyInt2
       {
           int func2(object obj);
       };
       

       public struct MyValueType : IMyInt
       {
           public Int32 a;
           public int func(object obj)
           {
             a = 5;
             this.func2(null);
             ToString();
             return 5;
           }
           public int func2(object obj)
           {
               return 5;
           }    
       }

       static void Main(string[] args)
       {
           MyValueType a;
           IMyInt b;
           a.a = 3;
           a.func(null);
           b = a;
           b.func(null);
           
       }
   }


 
euru ©   (2010-12-06 12:24) [402]

Если в языке используются только значимые типы, то для чего нужны операции boxing/unboxing?


 
oxffff ©   (2010-12-07 09:43) [403]


> euru ©   (06.12.10 12:24) [402]
> Если в языке используются только значимые типы, то для чего
> нужны операции boxing/unboxing?


Это кому вопрос? :)


 
oxffff ©   (2010-12-07 09:49) [404]

Сейчас в YAR есть только значимые типы.
Возможности по динамической аллокации отсутствуют.
Однако в языке есть конструктор типа - типизированный указатель и операторы @ и ^.
Поэтому если будут интересные выкладки по value type, захвату, и общей семантике, то можно будет реализовать их в одном из ответвлений YAR.  И потестить usability. :)


 
euru ©   (2010-12-07 12:04) [405]


> oxffff ©   (07.12.10 09:43) [403]

> Это кому вопрос? :)

Всем, кто сможет объяснить необходимость этой операции. :)


 
oxffff ©   (2010-12-07 12:31) [406]


> euru ©   (07.12.10 12:04) [405]
>
> > oxffff ©   (07.12.10 09:43) [403]
>
> > Это кому вопрос? :)
>
> Всем, кто сможет объяснить необходимость этой операции.
> :)


Boxed type - имеет схожесть с вариантным типом.


 
Mystic ©   (2010-12-07 13:03) [407]


> Всем, кто сможет объяснить необходимость этой операции.
> :)


В C# она часто скрыта. А так можешь рассматривать как приведение типа.


 
euru ©   (2010-12-07 14:15) [408]


> oxffff ©   (07.12.10 09:49) [404]

> Однако в языке есть конструктор типа - типизированный указатель
> и операторы @ и ^.

С какой целью они введены в язык?


> Поэтому если будут интересные выкладки по value type, захвату,
>  и общей семантике, то можно будет реализовать их в одном
> из ответвлений YAR.  И потестить usability. :)

Моих знаний, скорее всего, будет недостаточно, чтобы сделать полное формальное описание. В общих же чертах идея выглядит следующим образом.
В языке используются переменные только значимых типов. Понятие указателей и ссылок полностью отсутствует. Однако компилятор на основе анализа исходного кода сам решает, как лучше представить переменную (в виде значения либо ссылки на некий объект) и где лучше её хранить (в стеке, куче либо где-то ещё).
Все типы, скорее всего, должны обладать некими атрибутами, позволяющими компилятору управлять этими типами (например, для того чтобы можно было применять арифметические операции, у типа дложен быть атрибут, означающий что он числовой тип).
Пока придерживаюсь варианта, что должна быть явная инициализация переменных. В случае отсутствия инициализации компилятор выдаёт предупреждение. Хотя не уверен, что это возможно.

Вот как-то так. Хотелось бы критики, чтобы уточнить эту идею либо согласиться в её невозможности.


 
oxffff ©   (2010-12-07 14:26) [409]


> euru ©   (07.12.10 14:15) [408]
> > oxffff ©   (07.12.10 09:49) [404]
>
> > Однако в языке есть конструктор типа - типизированный
> указатель
> > и операторы @ и ^.
>
> С какой целью они введены в язык?


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


> Однако компилятор на основе анализа исходного кода сам решает,
>  как лучше представить переменную (в виде значения либо
> ссылки на некий объект) и где лучше её хранить (в стеке,
>  куче либо где-то ещё).


Было бы здорово увидить конкретный пример с неформальным описанием в каком случае компилятор решает что переменная должна быть на стеке, а в каком в куче.


 
euru ©   (2010-12-07 15:17) [410]


> oxffff ©   (07.12.10 12:31) [406]
> Mystic ©   (07.12.10 13:03) [407]

Правильно ли я понимаю, что если бы дженерики были изначально, то боксинг бы не понадобился?


 
euru ©   (2010-12-07 15:52) [411]


> oxffff ©   (07.12.10 14:26) [409]

> Планирую создавать динамические структруры данных по старинке.

А точно для этих целей нужны эти операторы? Разве по контексту компилятор не сможет понять, когда данные необходимо создавать динамически?


> Было бы здорово увидить конкретный пример с неформальным
> описанием в каком случае компилятор решает что переменная
> должна быть на стеке, а в каком в куче.

Например, если компилятор определит, что время жизни переменной меньше времени жизни кода, в которой она используется, то можно выделять в стеке (к примеру, локальная переменная в подпрограмме).
Другой пример. Если компилятор видит, что возвращаемое из подпрограммы значение присваивается локальной переменной в вызывающем коде, то для этого возвращаемого значения можно зарезервировать память в стеке вызывающего кода.


 
oxffff ©   (2010-12-07 15:52) [412]


> euru ©   (07.12.10 15:17) [410]
>
> > oxffff ©   (07.12.10 12:31) [406]
> > Mystic ©   (07.12.10 13:03) [407]
>
> Правильно ли я понимаю, что если бы дженерики были изначально,
>  то боксинг бы не понадобился?


В большинстве да. IMHO.
Особенно с учетом введения DLR.

Очень интересный пример

http://www.gamedev.ru/flame/forum/?id=127498


 
oxffff ©   (2010-12-07 16:19) [413]


> euru ©   (07.12.10 15:52) [411]
>
> > oxffff ©   (07.12.10 14:26) [409]
>
> > Планирую создавать динамические структруры данных по старинке.
>
>
> А точно для этих целей нужны эти операторы? Разве по контексту
> компилятор не сможет понять, когда данные необходимо создавать
> динамически?


В YAR я сделаю так, как это делается например в Pascal.


> Например, если компилятор определит, что время жизни переменной
> меньше времени жизни кода, в которой она используется, то
> можно выделять в стеке (к примеру, локальная переменная
> в подпрограмме).
> Другой пример. Если компилятор видит, что возвращаемое из
> подпрограммы значение присваивается локальной переменной
> в вызывающем коде, то для этого возвращаемого значения можно
> зарезервировать память в стеке вызывающего кода.


Все же примеры на псевдоязыке были бы более нагляднее и понятнее.

Например

function abc:integer;   <-значение результата динамически
a:integer;   <-стек.
begin
result:=a+1;  
end;

function ReturnFunction():  function ():integer <-значение результата динамически
a:integer;  <-куча
begin
result:=function :integer
          begin
          result:=a;
          end;
end;

Однако у меня нет опыта написания на функциональном языке.
Но чутье подсказывает функциональную природу подхода(свободные и связанные переменные) этих примеров. IMHO.


 
euru ©   (2010-12-07 23:07) [414]


> oxffff ©   (07.12.10 16:19) [413]

> В YAR я сделаю так, как это делается например в Pascal.

В [360] я и предположил, что в [358] предлагается обсудить YAR. :)
Я не предлагаю из YAR убрать операторы @ и ^. Мне просто интересно, какие трудности могут возникнуть в случае их отсутствия в языке и можно ли их решить без ввода этих операторов.


> Все же примеры на псевдоязыке были бы более нагляднее и
> понятнее.

Ок. Рассмотрим предложенные примеры.

Для начала я введу такое понятие как "дескриптор" - это объект, предоставляющий компилятору необходимую информацию для правильной интерпретации элемента языка во время компиляции.

function abc:integer;
Компилятор создаёт дескриптор функции abc, в котором сохраняет, пустой список входящих параметров и список, состоящий из одного элемента, исходящих параметров. Так как тип исходящего параметра функции -- Integer, то значение этого параметра может храниться в регистре, стеке или кучи, что и записывается в дескриптор исходящего параметра. Необходимый вариант будет определяться переменной, которой присваивается значение исходящего параметра.

a:integer;
Компилятор создаёт дескриптор локальной переменной a, определяет её тип как Integer, а место хранения - регистр, стек, куча.

begin
  result:=a+1;
 
Здесь компилятор должен выдать сообщение об ошибке, так как переменная a ещё не инициализирована. Но пусть перед этой строкой имеется, например, строка a := rand().

end;
Компилятор видит, переменная а используется только как промежуточное значение, используемое для вычисления исходящего параметра. Поэтому он выкидывает эту перенменную, а выражение rand()+1 присваивает непосредственно исходящему параметру. В принципе, компилятор может принять решение вообще определить эту функцию как inline.

function ReturnFunction():  function ():integer
a:integer;  <-куча
begin
result:=function :integer
         begin
         result:=a;
         end;
end;

Здесь, в принципе, тоже ошибка с инициализацией локальной переменной а. И если, допустим, для её инициализации используется код типа a := rand();, то анализ покажет, что функция ReturnFunction() возвращает функцию rand(). Поэтому здесь также компилятор может отказаться от использования в функции переменной а, а в месте вызова функции ReturnFunction() вызывать непосредственно функцию rand().


 
oxffff ©   (2010-12-08 00:14) [415]


> euru ©   (07.12.10 23:07) [414]


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

Считаем что локация необходима(от нее нельзя избавиться) как установить где она должна быть размещена?
Мне все же бы хотелось больше конкретных примеров алгоритма(или его наброски) установления именно времени жизни локациии - стек, куча.

Опять же наши функции чистые? Есть ли ссылки?


> а в месте вызова функции ReturnFunction() вызывать непосредственно
> функцию rand().


Не получится поскольку ReturnFunction возравщает функцию, а не значение.


 
Mystic ©   (2010-12-08 14:13) [416]


> Правильно ли я понимаю, что если бы дженерики были изначально,
>  то боксинг бы не понадобился?


Тяжело все случаи закрывать generic-ами. Часто есть поля типа Data, Tag, где пользователь может хранить свои собственные данные. Если эти поля определить как Object, то как тогда в него занести int? А делать int полноценным Obejct дорого.


 
euru ©   (2010-12-09 13:43) [417]


> oxffff ©   (08.12.10 00:14) [415]

> Мне все же бы хотелось больше конкретных примеров алгоритма(или
> его наброски) установления именно времени жизни локациии
> - стек, куча.

Если только в качестве наброска. Например, локальные переменные. Время их жизни ограничивается временем жизни подпрограммы. Изначально для всех локальных переменных подпрограммы определяется наиболее эффективный тип хранилища данных (например, для элементарных типов - регистры, для остальных - стек). Если переменная передаётся в качестве параметра в другую подпрограмму, то её тип хранилища определяется типом хранилища параметра. Если переменная присваивается другой переменной либо возвращается из подпрограммы, то её тип хранилища определяется типом хранилища переменной, принимающее это значение. Если для всех переменных элементарных типов не хватило регистров, то часть их перемещается в стек. Если же, например, по каким-либо причинам объём стека окажется меньше суммарного объёма всех претендующих на него переменных, то можно в стеке поместить максимально возможное количество переменных, а остальные переменные определить в куче. После этого можно генерировать код в соответствии с определёнными местами хранения переменных.


> Опять же наши функции чистые? Есть ли ссылки?

В [348] я вскользь коснулся этих вопросов.
Функции имеют только входящие и возвращаемые параметры. Например,
(a, b) := func(b, c);


> > а в месте вызова функции ReturnFunction() вызывать непосредственно
> > функцию rand().
> Не получится поскольку ReturnFunction возравщает
> функцию, а не значение.

Некорректно выразился. "В месте присваивания результата функции ReturnFunction() присвоить непосредственно функцию rand()."


 
euru ©   (2010-12-09 13:44) [418]


> Mystic ©   (08.12.10 14:13) [416]


> Часто есть поля типа Data, Tag, где пользователь может хранить
> свои собственные данные.

А разве эти поля нельзя сделать параметризованными?


 
Mystic ©   (2010-12-09 13:54) [419]

> А разве эти поля нельзя сделать параметризованными?

Можно, но для разработчиков либ это большой геморрой протаскивать все эти поля через generic. Поле Tag появляется в классе TComponent, и его придется тащить сквозь всю иерархию TControl, TWinControl, TCustomForm, TForm, ... При разработке своих компонентов мне также придется с ним мучаться. И все только ради призрачной цели, чтобы в 1% случаев, когда оно юзается, не делать лишнее приведение типа?

Не говоря о проблемах с DLL, в которой метод возвращает TForm.



Страницы: 1 2 3 4 5 6 7 8 9 
10 11 вся ветка

Форум: "Прочее";
Текущий архив: 2011.03.20;
Скачать: [xml.tar.bz2];

Наверх





Память: 1.55 MB
Время: 0.085 c
15-1291659561
bss
2010-12-06 21:19
2011.03.20
Как определяют PR и тИЦ сайтов?


11-1227810366
Jon
2008-11-27 21:26
2011.03.20
Activemovie


6-1200848613
Maloj2007
2008-01-20 20:03
2011.03.20
Связь TIdTCPServer и TIdTCPClient


15-1291489764
Артём
2010-12-04 22:09
2011.03.20
Дельфи 2010


15-1289326102
DiamondShark
2010-11-09 21:08
2011.03.20
Высокий/низкий уровень, ручное/автоматическое управление





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский