dotnet / dotnet/dotnet-api-docs

Information on LayoutKind.Sequential and LayoutKind.Explicit + FieldOffset appears to be inaccurate

Open
#4,325 1 comment 0 reactions 0 assignees View on GitHub
area-System.Runtime.InteropServices Pri3 untriaged
Dominant language
C#
Stars
949
Forks
1.7k
Avg merge
3d 27m
Merged PRs (30d)
49

Description

Before making a PR, I would like to discuss/verify this change first, as there appears to be a lot of confusion around the subject. It's about this file: https://github.com/dotnet/dotnet-api-docs/blob/master/xml/System.Runtime.InteropServices/StructLayoutAttribute.xml, which is [here in the docs](https://docs.microsoft.com/en-us/dotnet/api/system.runtime.interopservices.structlayoutattribute?view=netcore-3.1).

My point is specifically about the Remarks section.

* [This document on LayoutKind.Explicit](https://docs.microsoft.com/en-us/dotnet/api/system.runtime.interopservices.layoutkind?view=netcore-3.1#System_Runtime_InteropServices_LayoutKind_Explicit) says it only applies to unmanaged memory layout of types
* Whereas [the main document](https://docs.microsoft.com/en-us/dotnet/api/system.runtime.interopservices.structlayoutattribute?view=netcore-3.1) explicitly states it is applied to managed and unmanaged memory, for blittable and non-blittable types. Furthermore, it says about `Sequential` that it is applied to blittable types only. Relevant quote:

> Use the attribute with LayoutKind.Explicit to control the precise position of each data member. This affects both managed and unmanaged layout, for both blittable and non-blittable types.

ECMA-335 in section II.22.8 says about the `ClassLayout` table that (note the "shall" in this sentence):

> The ClassLayout table is used to define how the fields of a class or value type shall be laid out by the CLI. (Normally, the CLI is free to reorder and/or insert gaps between the fields defined for a class or value type.)

Furthermore it goes on to explain in what type hierarchies it is applicable, mainly: if the hierarchy contains a type marked `Auto` (like `DateTime`) it is considered an error. It does not seem to say if such types, if they are a field of the struct, can be arranged to specific positions (this [SO question suggests it has influence](https://stackoverflow.com/questions/4132533/why-does-layoutkind-sequential-work-differently-if-a-struct-contains-a-datetime)).

Note that there are several bugs in relation to have the CLR should behave, but as far as I can tell they seem to follow what the ECMA spec says. The way I read it is that the rules are as follows:

* `Sequential` is applicable to managed and unmanaged types (probably: only when blittable)
* `Explicit` is applicable to managed and unmanaged, blittable and non-blittable types alike (as one text in the docs states, but others do not).
* If any type in the hierarchy has no layout (through implicit/explicit `Auto`) then the attribute is ignored (or an error?).
* Both are always honored when marshaling the type to an unmanaged one (unless the hierarchy forbids it)
* Neither applies to generics

I'm curious about other gotchas w.r.t. when the main rule doesn't apply

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.