исправлена ​​инструкция в C # и управляемый указатель в коде IL - PullRequest
6 голосов
/ 26 июня 2011

В небезопасном коде в C # я назначил указатель на управляемую переменную типа массива:

int[] array = new int[3];
...
fixed (int* ptr = array)
{
    //some code
}

Затем я посмотрел на соответствующую часть кода IL:

.locals init ([0] int32[] 'array',
       [1] int32& pinned ptr)

И ямне интересно, так как это небезопасный код, а int* ptr является объявлением неуправляемого указателя (или я так думаю на данный момент), почему в коде IL не пишется int32* ptr вместо int32& ptr?

Ответы [ 3 ]

3 голосов
/ 26 июня 2011

http://www.ecma -international.org / публикации / стандарты / Ecma-335.htm

Страница 334

"1.1.5.2 Управляемые указатели (type &)

1.2 Управляемые указатели (&) могут указывать на локальную переменную, аргумент метода, поле объекта, поле типа значения, элемент массива, статический элементполе или адрес, в котором будет храниться элемент после конца массива (для индексов указателей в управляемые массивы). Управляемые указатели не могут быть нулевыми. (Они должны сообщаться сборщику мусора, даже если они это делаютне указывать на управляемую память) "

Page 149

7.1.2 закреплено

Кодировка подписи для закрепленного должна появляться только в сигнатурах, которые описывают локальнуюпеременные (§15.4.1.3). Пока выполняется метод с закрепленной локальной переменной, VES не должен перемещать объект, на который ссылается локальный. То есть, если реализация CLI использует сборщик мусора, который перемещает объекты, сборщик долженне перемещать объекты, на которые ссылается активная закрепленная локальная переменная.[Обоснование: если неуправляемые указатели используются для разыменования управляемых объектов, эти объекты должны быть закреплены.Это происходит, например, когда управляемый объект передается методу, предназначенному для работы с неуправляемыми данными.конечное обоснование]

Я согласен с Гансом относительно рационального выбора дизайна языка msil.


Эти две вещи различны:

int[] arry = new int[5];

fixed (int* ptr = arry)
{
  ...
}

против

int* ptr = stackalloc int[5];

Если вы посмотрите на IL, созданный для второго, вы увидите это (что, я думаю, то, что вы ожидаете):

.locals init ([0] int32* ptr)

В первой версии (вашей версии) вы указываете на экземпляр System.Array (управляемого типа).В моей версии (с использованием stackalloc) вы указываете на то, что, я думаю, вы ожидаете указать на ... блок памяти, достаточно большой для 5 дюймов.

2 голосов
/ 26 июня 2011

Ildasm был написан программистом C ++ в Microsoft.Язык, где разница между указателями и ссылками имеет большое значение.Ссылка на C ++ под капотом также является указателем, но он гарантированно никогда не будет нулевым.Ссылка синтаксически идентифицируется как &, указатель - *.

. В данном случае существует разница между указателем и указанным значением.Указанное значение может быть нулевым, но ссылка на указатель никогда не бывает нулевой.Переменная «массив» гарантированно присутствует в кадре стека, и поэтому ее ссылка имеет ненулевое значение.Только это значение может быть нулевым.Что происходит, когда массив не инициализирован.Этот уровень косвенности сделал указатели непопулярными и в основном отсутствующими в языке C #.И CS101.

0 голосов
/ 26 июня 2011

c # - это управляемый кодированный язык, поэтому не будет никакого указателя.но есть класс-оболочка для использования указателей, возможно, из-за того, что вы заметили некоторую разницу в этих двух.

...