[英]Defining struct in Swift Mac App
我正在使用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。我在做什么錯誤嗎?
這只是需要將變量保持在4字節邊界對齊的結果。 在您的第一個示例中,將添加三個填充字節,以便AddressX,AddressY和AddressZ的地址正確對齊。 在第二個示例中,所有內容都已經對齊到4字節的邊界,因此不需要填充。
大小16並不正確,因為Swift不能保證本機Swift結構中字段的布局和對齊方式。 據推測,在當前版本的Swift中,它將UInt8
字段填充為4個字節,因此以下UInt32
字段為4字節對齊以提高性能。
無法保證Swift的未來版本將以相同的方式布局結構, 至少直到Swift ABI完成之前 。 Swift錯誤跟蹤器中存在幾個相關問題:
還要注意,如果需要ConfigData
數組,則應使用MemoryLayout<ConfigData>.stride
來測量大小,因為Swift可能會在數組元素之間包含填充(同樣出於性能考慮)。 您可能會發現ConfigData
兩種布局的步幅均為16。
如果您關心結構的字節布局,則需要在C中定義它,可能使用編譯器擴展來精確控制編譯器在哪里插入(或不插入)填充。
我有做錯什么嗎
不,沒錯。 您只需要了解對齊方式即可 。
Swift編譯器將UInt32
成員對齊到4字節邊界,並且您知道, UInt8
用一個字節。 因此,您的第一個ConfigData
在memory(*)中表示為:
AddressType | |x|x|x|
AddressX | |
AddressY | |
AddressZ | |
其中x
表示填充字節以對齊后面的成員。
在第二個ConfigData
,內部表示為:
AddressX | |
AddressY | |
AddressZ | |
AddressType | |
在后一種情況下, MemoryLayout<ConfigData>.size
不計算尾隨未對齊字節。 由於可以在其中分配一些字節變量。
但是,如果您在數組中分配多個ConfigData
,則Swift會在底部添加填充字節。 因此, MemoryLayout<ConfigData>.stride
返回的計數為兩個ConfigData
均為16
。
(*)Swift不保證結構的成員分配。 並且在將來要聲明ABI穩定性之前,細節可能會更改。
似乎我來晚了,我的回答只是說明rob mayoff回答的一部分。 請仔細閱讀。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.