-
Notifications
You must be signed in to change notification settings - Fork 5.2k
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
reffrom 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.