Description
Description
Context: Found in .NET 9 when experimenting with ref struct
in P/Invoke scenarios. I want to make it clear that I'm not using "ref fields" but rather only "ref structs"; the fields of the struct are not ref
(pointer) but the type is of ref struct
(stack-only).
Reproduction Steps
using System;
using System.Runtime.InteropServices;
public class Program
{
[StructLayout(LayoutKind.Explicit, Size = 8, Pack = 8)]
public ref struct Foo
{
[FieldOffset(0)]
public Bar A;
[FieldOffset(4)]
public Bar B;
}
public ref struct Bar
{
public uint Value;
}
public static void Main()
{
var e = default(Foo);
e.A.Value = 1;
e.B.Value = 2;
Console.WriteLine("1 + 2 = " + (e.A.Value + e.B.Value));
}
}
Expected behavior
A ref struct
of explicit layout can have fields that are positioned using FieldOffset
attribute where the type of the field is a ref struct
without creating a runtime exception.
Actual behavior
When a ref struct
is using explicit struct layout, a System.TypeLoadException
can occur regarding the field offset of the struct's field which the type is another ref struct
.
Unhandled exception. System.TypeLoadException: Could not load type 'Foo' from assembly 'r2oeekw4.exe, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null' because it contains an object field at offset 4 that is incorrectly aligned or overlapped by a non-object field.
at Program.Main()
Regression?
No response
Known Workarounds
- Removing the
ref
from the nested struct.
Configuration
- .NET 9
- macOS Ventura 13.6.5
- Apple M1 (
osx-arm64
) - Not specific to any configuration.
Other information
Hypothesis: The word ref
in the context of a struct (stack-only) is confused to be in the context of a field (pointer); the field is mistaken for an object type with rules about field alignment when it's actually a struct.