【问题标题】:Defining struct in Swift Mac App在 Swift Mac App 中定义结构
【发布时间】:2018-01-20 11:30:29
【问题描述】:

我正在使用 Swift 在 Mac App 中定义一个结构

struct ConfigData {
    var AddressType : UInt8
    var AddressX : UInt32
    var AddressY : UInt32
    var AddressZ : UInt32
}

结构大小返回为 16(这是不正确的)但是当我改变 结构的顺序为

struct ConfigData {
    var AddressX : UInt32
    var AddressY : UInt32
    var AddressZ : UInt32
    var AddressType : UInt8
}

计数正确打印为 13。我做错了什么

【问题讨论】:

    标签: swift macos swift3


    【解决方案1】:

    这只是需要将变量保持在 4 字节边界对齐的结果。在您的第一个示例中,将添加三个字节的填充,以便正确对齐 AddressX、AddressY 和 AddressZ 的地址。在您的第二个示例中,所有内容都已在 4 字节边界对齐,因此不需要填充。

    【讨论】:

      【解决方案2】:

      大小 16 并没有错,因为 Swift 不保证原生 Swift 结构中字段的布局和对齐方式。据推测,在当前版本的 Swift 中,它会将 UInt8 字段填充为 4 个字节,因此以下 UInt32 字段为 4 字节对齐以提高性能。

      不保证未来版本的 Swift 会以相同的方式布局结构,at least until the Swift ABI is finalized。 Swift 错误跟踪器中存在几个相关问题:

      还要注意,如果你想要一个ConfigData 的数组,你应该使用MemoryLayout<ConfigData>.stride 来测量大小,因为 Swift 可能在数组元素之间包含填充(同样,为了性能)。您可能会发现ConfigData 的两个布局的步幅都是 16。

      如果您关心结构的字节布局,则需要在 C 中定义它,可能使用compiler extensions 来精确控制编译器插入(或不插入)填充的位置。

      【讨论】:

        【解决方案3】:

        我做错了什么

        不,没有错。你只需要知道对齐

        Swift 编译器将 UInt32 成员与 4 字节边界对齐,并且如您所知,UInt8 只占用一个字节。因此,您的第一个 ConfigData 在内存(*)中表示为:

        AddressType | |x|x|x|
        AddressX    |       |
        AddressY    |       |
        AddressZ    |       |
        

        其中x 表示填充字节以对齐以下成员。

        在您的第二个ConfigData 中,内部表示将是:

        AddressX    |       |
        AddressY    |       |
        AddressZ    |       |
        AddressType | |
        

        在后一种情况下,MemoryLayout<ConfigData>.size 不计算尾随未对齐字节。因为可以在那里分配一些字节变量。

        但是如果你在一个数组中分配多个ConfigData,Swift 会在底部添加填充字节。因此,MemoryLayout<ConfigData>.stride 为此目的返回计数,即16 对于ConfigData

        (*) Swift 不保证结构的成员分配。在 ABI 稳定性声明之前,细节可能会在未来发生变化。


        似乎我迟到了,我的回答只是说明了 rob mayoff 回答的一部分。请仔细阅读。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2016-04-06
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2016-07-18
          • 2014-08-18
          相关资源
          最近更新 更多