Search code examples
c#.netvb.netstructunions

(.net) Is there any intrinsic difference between .net Explicit structs and c++ unions?


That is the question. Is there anything you can do with c++ unions that you can't with c# Explicit structs?


Solution

  • C# explicit structs have some problems when it comes to references / pointer-sized members.

    Because you must explicitly specify the location, but "sizeof(IntPtr)" is not a compile-time constant (unlike C++ sizeof), it is impossible to use pointer-sized members in explicit structs when your assembly should be usable in both 32-bit and 64-bit processes.

    Also, it is possible to use explicit structs to "convert" between references and pointers:

    [StructLayout(LayoutKind.Explicit)]
    struct Test
    {
        [FieldOffset(0)]
        public IntPtr ptr;
        [FieldOffset(0)]
        public string str;
    }
    

    When you do this, your assembly will require unsafe code permission; and there's the problem that the GC won't know what to do with the struct content - is it a pointer the GC should track, or is it just an integer?

    So to answer your question: "Is there anything you can do with c++ unions that you can't with c# Explicit structs?"

    Yes, it's sometimes useful in C++ to squeeze two bits of data into the lower bits of a pointer. That is possible because the two lowermost bits of pointers will always be 0 when the pointer is aligned.

    Heck, if you're writing a doubly-linked list of two-bit integers, you could even store both pointers and the data in 32 bits! ("prev ^ next ^ data", see XOR linked list)

    However, you cannot do anything like that in C#, as you'd confuse the GC.