That is the question. Is there anything you can do with c++ unions that you can't with c# Explicit structs?
views:
66answers:
2No, not really. The LayoutKind attribute is a way to Marshall data into C++ unions in interop. It's actually far more flexible than the union keyword in C++, since you have complete control over the layout in C# with structs.
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.