Tutorial :What is the underlying reason for not being able to put arrays of pointers in unsafe structs in C#?



Question:

If one could put an array of pointers to child structs inside unsafe structs in C# like one could in C, constructing complex data structures without the overhead of having one object per node would be a lot easier and less of a time sink, as well as syntactically cleaner and much more readable.

Is there a deep architectural reason why fixed arrays inside unsafe structs are only allowed to be composed of "value types" and not pointers?

I assume only having explicitly named pointers inside structs must be a deliberate decision to weaken the language, but I can't find any documentation about why this is so, or the reasoning for not allowing pointer arrays inside structs, since I would assume the garbage collector shouldn't care what is going on in structs marked as unsafe.

Digital Mars' D handles structs and pointers elegantly in comparison, and I'm missing not being able to rapidly develop succinct data structures; by making references abstract in C# a lot of power seems to have been removed from the language, even though pointers are still there at least in a marketing sense.

Maybe I'm wrong to expect languages to become more powerful at representing complex data structures efficiently over time.


Solution:1

I'm just guessing, but it might have to do with different pointer sizes for different target platforms. It seems that the C# compiler is using the size of the elements directly for index calculations (i.e. there is no CLR support for calculating fixed sized buffers indices...)

Anyway you can use an array of ulongs and cast the pointers to it:

unsafe struct s1  {    public int a;    public int b;  }    unsafe struct s  {    public fixed ulong otherStruct[100];  }    unsafe void f() {    var S = new s();    var S1 = new s1();    S.otherStruct[4] = (ulong)&S1;    var S2 = (s1*)S.otherStruct[4];  }  


Solution:2

One very simple reason: dotNET has a compacting garbage collector. It moves things around. So even if you could create arrays like that, you would have to pin every allocated block and you would see the system slow down to a crawl.

But you are trying to optimize based on an assumption. Allocation and cleanup of objects in dotNET is highly optimized. So write a working program first and then use a profiler to find your bottlenecks. It will most likely not be the allocation of your objects.

Edit, to answer the latter part:

Maybe I'm wrong to expect languages to become more powerful at representing complex data structures efficiently over time.

I think C# (or any managed language) is much more powerful at representing complex data structures (efficiently). By changing from low level pointers to garbage collected references.


Solution:3

Putting a fixed array of pointers in a struct would quickly make it a bad candidate for a struct. The recommended size limit for a struct is 16 bytes, so on a x64 system you would be able to fit only two pointers in the array, which is pretty pointless.

You should use classes for complex data structures, if you use structures they become very limited in their usage. You wouldn't for example be able to create a data structure in a method and return it, as it would then contain pointers to structs that no longer exists as they were allocated in the stack frame of the method.


Note:If u also have question or solution just comment us below or mail us on toontricks1994@gmail.com
Previous
Next Post »