LayoutKind.Sequential nie następuje, gdy substruct ma LayoutKind.Explicit

Podczas uruchamiania tego kodu:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices;

namespace StructLayoutTest
{
    class Program
    {
        unsafe static void Main()
        {
            Console.WriteLine(IntPtr.Size);
            Console.WriteLine();


            Sequential s = new Sequential();
            s.A = 2;
            s.B = 3;
            s.Bool = true;
            s.Long = 6;
            s.C.Int32a = 4;
            s.C.Int32b = 5;

            int* ptr = (int*)&s;
            Console.WriteLine(ptr[0]);
            Console.WriteLine(ptr[1]);
            Console.WriteLine(ptr[2]);
            Console.WriteLine(ptr[3]);
            Console.WriteLine(ptr[4]);
            Console.WriteLine(ptr[5]);
            Console.WriteLine(ptr[6]);
            Console.WriteLine(ptr[7]);  //NB!


            Console.WriteLine("Press any key");
            Console.ReadKey();
        }

        [StructLayout(LayoutKind.Explicit)]
        struct Explicit
        {
            [FieldOffset(0)]
            public int Int32a;
            [FieldOffset(4)]
            public int Int32b;
        }

        [StructLayout(LayoutKind.Sequential, Pack = 4)]
        struct Sequential
        {
            public int A;
            public int B;
            public bool Bool;
            public long Long;
            public Explicit C;
        }
    }
}

Spodziewam się, że to wyjście ZARÓWNO na x86 i x64:
4 lub 8 (w zależności od x86 lub x64)

2
3
1
6
0
4
5
Śmieci

Co otrzymuję zamiast na x86:
4

6
0
2
3
1
4
5
Śmieci

Co otrzymuję zamiast x64:
8

6
0
2
3
1
0
4
5

Więcej:
- Problem znika, gdy usuwam atrybuty LayoutKind.Explicit i FieldOffset.
- Problem zniknie po usunięciu pola Bool.
- Problem znika, gdy usuwam pole Długie.
- Zauważ, że na x64 wydaje się, że parametr atrybutu Pack = 4 jest również ignorowany?

Dotyczy to .Net3.5, a także .Net4.0

Moje pytanie: czego mi brakuje? Czy jest to błąd?
Znalazłem podobne pytanie:
Dlaczego LayoutKind.Sequential działa inaczej, jeśli struktura zawiera pole DateTime?
Ale w moim przypadku układ zmienia się nawet wtedy, gdy zmienia się atrybut podstruktury, bez żadnych zmian w typach danych. Nie wygląda to na optymalizację. Poza tym chciałbym podkreślić, że inne pytanie wciąż pozostaje bez odpowiedzi.
W tym drugim pytaniu wspominają, że układ jest przestrzegany podczas korzystania z Marshallingu. Nie testowałem tego osobiście, ale zastanawiam się, dlaczego układ nie jest przestrzegany w przypadku niebezpiecznego kodu, ponieważ wszystkie odpowiednie atrybuty wydają się być na miejscu? Czy dokumentacja wspomina gdzieś, że te atrybuty są ignorowane, chyba że przeprowadzane jest Marshalling? Czemu?
Biorąc to pod uwagę, czy mogę nawet oczekiwać LayoutKind.Zrozumiałe, że działa niezawodnie za niebezpieczny kod?
Co więcej, dokumentacja wspomina motyw zachowania struktur o oczekiwanym układzie:

Aby zmniejszyć problemy związane z układem związane z wartością Auto, C #, Visual Basic i kompilatorami C ++, określ układ sekwencyjny dla typów wartości.


Ale ten motyw najwyraźniej nie dotyczy niebezpiecznego kodu?

questionAnswers(1)

yourAnswerToTheQuestion