dotnet / dotnet/dotnet-api-docs
Information on LayoutKind.Sequential and LayoutKind.Explicit + FieldOffset appears to be inaccurate
- 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
Assessment
This issue has not been assessed yet.