-
Notifications
You must be signed in to change notification settings - Fork 6k
Description
Breaking Change: Disallow loading non-Explicit types with explicit field offsets
Description
Starting in .NET 10 Preview 4, the .NET runtime enforces stricter validation for type layouts. Specifically, the runtime now throws a TypeLoadException
if a type with a non-explicit layout (e.g., Auto
or Sequential
) specifies explicit field offsets using the [FieldOffset]
attribute. This change aligns the runtime's behavior with the ECMA-335 specification, which only permits explicit field offsets for types with an Explicit
layout.
Previously, the runtime ignored explicit field offsets on non-explicit layout types, which could lead to unexpected behavior or incorrect assumptions about memory layout.
This change was introduced in PR #113500.
Version
This breaking change was introduced in .NET 10 Preview 4.
Previous behavior
In earlier versions of .NET, the runtime ignored explicit field offsets on types with Auto
or Sequential
layouts. For example:
using System;
using System.Runtime.InteropServices;
[StructLayout(LayoutKind.Sequential)]
public struct MyStruct
{
[FieldOffset(0)] // Ignored in .NET versions prior to 10 Preview 4
public int Field1;
[FieldOffset(4)] // Ignored in .NET versions prior to 10 Preview 4
public int Field2;
}
class Program
{
static void Main()
{
Console.WriteLine("Struct loaded successfully.");
}
}
The above code would execute without error, and the [FieldOffset]
attributes would be ignored.
New behavior
Starting in .NET 10 Preview 4, the runtime enforces the ECMA-335 specification and throws a TypeLoadException
if a type with Auto
or Sequential
layout specifies explicit field offsets. The following code will now throw an exception:
using System;
using System.Runtime.InteropServices;
[StructLayout(LayoutKind.Sequential)]
public struct MyStruct
{
[FieldOffset(0)] // Causes a TypeLoadException in .NET 10 Preview 4 and later
public int Field1;
[FieldOffset(4)] // Causes a TypeLoadException in .NET 10 Preview 4 and later
public int Field2;
}
class Program
{
static void Main()
{
Console.WriteLine("Struct loaded successfully.");
}
}
Exception thrown:
System.TypeLoadException: Explicit field offsets are not allowed on types with Sequential or Auto layout.
Type of breaking change
- Binary incompatible: Existing binaries that define non-explicit layout types with explicit field offsets will fail to load.
- Behavioral change: Existing binaries might behave differently at runtime due to the stricter validation.
Reason for change
This change was introduced to align the .NET runtime with the ECMA-335 specification, which explicitly disallows explicit field offsets on types with Auto
or Sequential
layouts. The previous behavior of ignoring these offsets was non-compliant and could lead to unexpected behavior or incorrect assumptions about memory layout.
Recommended action
To resolve this issue, developers should update their code to use LayoutKind.Explicit
for types that specify explicit field offsets. For example:
using System;
using System.Runtime.InteropServices;
[StructLayout(LayoutKind.Explicit)] // Use Explicit layout
public struct MyStruct
{
[FieldOffset(0)]
public int Field1;
[FieldOffset(4)]
public int Field2;
}
class Program
{
static void Main()
{
Console.WriteLine("Struct loaded successfully.");
}
}
Alternatively, if explicit field offsets are not required, remove the [FieldOffset]
attributes and rely on the default behavior of Sequential
or Auto
layout.
Affected APIs
This change does not directly affect specific APIs but impacts the runtime behavior of types defined with the following attributes:
[StructLayout(LayoutKind.Sequential)]
[StructLayout(LayoutKind.Auto)]
[FieldOffset]
Feature area
- Interop
Additional resources
For further assistance, please contact .NET Breaking Change Notifications.
Metadata
Metadata
Assignees
Labels
Type
Projects
Status