Fixed operator in C # and managed pointer in IL code

In unsafe code in C #, I assigned a pointer to a managed variable like an array:

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

Then I looked at the corresponding part of the IL code:

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

And I wonder, since this is unsafe code, and int* ptr is an unmanaged pointer declaration (or, I think, at the moment), why int32* ptr and not int32& ptr not written in IL-code

+6
source share
3 answers

http://www.ecma-international.org/publications/standards/Ecma-335.htm

Page 334

"1.1.5.2 Managed pointers (type &)

1.2 Managed pointers (&) can point to a local variable, a method argument, an object field, a value field type, an array element, a static field, or the address in which the element will be just beyond the end of the array (for pointers to pointers to managed arrays). Managed pointers cannot be null. (They must be reported to the garbage collector, even if they do not indicate managed memory) "

Page 149

7.1.2 pinned

Signature encoding for pinning should appear only in signatures describing local variables (Β§15.4.1.3). When using a method with a fixed local variable, VES should not move the object to which the local belongs. That is, if the CLI implementation uses a garbage collector that moves objects, the collector should not move objects referenced by the active bound local variable. [Justification. If unmanaged pointers are used to dereference managed objects, these objects must be pinned. This happens, for example, when a managed object is passed to a method designed to work with unmanaged data. final rationale]

I agree with Hans regarding the rational choice of msil language design.


These two things are different:

 int[] arry = new int[5]; fixed (int* ptr = arry) { ... } 

against.

 int* ptr = stackalloc int[5]; 

If you look at the IL created for the second, you will see this (which, I think, you expect):

 .locals init ([0] int32* ptr) 

In the first version (your version), you point to an instance of System.Array (a managed type). In my version (using stackalloc) you indicate that, I think, you expect to point to ... a memory block large enough for 5 ints.

+3
source

Ildasm was written by a C ++ programmer at Microsoft. A language where the difference between pointers and links is a big deal. The C ++ link under the hood is also a pointer, but one that will never be zero. The link is syntactically identified by the & symbol, the pointer is *.

In this case, there is a difference between the pointer and the value specified in the pointer. The specified value may be null, but a pointer reference is never null. The variable "array" is guaranteed to be present in the stack frame, and therefore its reference has a nonzero value. Only its value can be zero. This happens when the array is not initialized. This level of indirection made pointers unpopular and mostly absent in C #. And CS101.

+2
source

C # is a managed coded language, so there will be no pointer. but there is a wrapper class for using pointers, perhaps because of this you notice some difference in the two.

-5
source

Source: https://habr.com/ru/post/891360/


All Articles