Not UB, illegal. Per ECMA 335, II.10.7:
It is possible to overlap fields in this way, though offsets occupied by an object reference shall not overlap with offsets occupied by a built-in value type or a part of another object reference.
Per .NET 8.0:
using System.Runtime.InteropServices;
var s = new S { Bar = "Baz" };
[StructLayout(LayoutKind.Explicit)]
public struct S {
[FieldOffset(0)] public UInt64 Foo;
[FieldOffset(0)] public Object Bar;
}
compiles, but throws
System.TypeLoadException: Could not load type 'S' from assembly 'foo, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null' because it contains an object field at offset 0 that is incorrectly aligned or overlapped by a non-object field.
Interestingly, this code elicits a warning
ILC: Method '[foo]Program.$(string[])' will always throw because: Failed to load type 'S' from assembly 'foo, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null' because of field offset '0'
from the AOT compiler, but none from the C# compiler.