Why does struct alignment depend on whether a field type is primitive or user-defined?

后端 未结 4 872
天涯浪人
天涯浪人 2020-12-07 14:38

In Noda Time v2, we\'re moving to nanosecond resolution. That means we can no longer use an 8-byte integer to represent the whole range of time we\'re interested in. That ha

4条回答
  •  不知归路
    2020-12-07 15:00

    Summary see @Hans Passant's answer probably above. Layout Sequential doesn't work


    Some testing:

    It is definitely only on 64bit and the object reference "poisons" the struct. 32 bit does what you are expecting:

    Environment: CLR 4.0.30319.34209 on Microsoft Windows NT 6.2.9200.0 (32 bit)
    ConsoleApplication1.Int32Wrapper: 4
    ConsoleApplication1.TwoInt32s: 8
    ConsoleApplication1.TwoInt32Wrappers: 8
    ConsoleApplication1.ThreeInt32Wrappers: 12
    ConsoleApplication1.Ref: 4
    ConsoleApplication1.RefAndTwoInt32s: 12
    ConsoleApplication1.RefAndTwoInt32Wrappers: 12
    ConsoleApplication1.RefAndThreeInt32s: 16
    ConsoleApplication1.RefAndThreeInt32Wrappers: 16
    

    As soon as the object reference is added all the structs expand to be 8 bytes rather their 4 byte size. Expanding the tests:

    Environment: CLR 4.0.30319.34209 on Microsoft Windows NT 6.2.9200.0 (64 bit)
    ConsoleApplication1.Int32Wrapper: 4
    ConsoleApplication1.TwoInt32s: 8
    ConsoleApplication1.TwoInt32Wrappers: 8
    ConsoleApplication1.ThreeInt32Wrappers: 12
    ConsoleApplication1.Ref: 8
    ConsoleApplication1.RefAndTwoInt32s: 16
    ConsoleApplication1.RefAndTwoInt32sSequential: 16
    ConsoleApplication1.RefAndTwoInt32Wrappers: 24
    ConsoleApplication1.RefAndThreeInt32s: 24
    ConsoleApplication1.RefAndThreeInt32Wrappers: 32
    ConsoleApplication1.RefAndFourInt32s: 24
    ConsoleApplication1.RefAndFourInt32Wrappers: 40
    

    As you can see as soon as the reference is added every Int32Wrapper becomes 8 bytes so isn't simple alignment. I shrunk down the array allocation incase it was LoH allocation which is differently aligned.

提交回复
热议问题