2017-08-11 19 views
1

私は(正しくない)構造体サイズは16として返されスウィフト定義スウィフトマックで構造体のApp

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

を使ってMac Appの構造を定義していますが、私は構造の順に を変更したとき

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

カウントが13として正しく印刷されて、私が間違って

答えて

4

やっているものはあります。これは、整列の変数を維持する必要性の結果だけです4バイトの境界で。あなたの最初の例では、AddressX、AddressY、およびAddressZのアドレスが適切に揃うように、3バイトのパディングが追加されます。 2番目の例では、すべてが4バイトの境界に揃えられているため、パディングは必要ありません。

2

サイズ16は、SwiftがネイティブSwift構造体のフィールドのレイアウトと配置について保証していないため、間違いではありません。おそらく、現在のバージョンのSwiftでは、UInt8フィールドを4バイトにパディングしているので、次のUInt32フィールドはパフォーマンスのために4バイト整列されます。

Swiftの将来のバージョンでも、同じ方法で構造がレイアウトされるという保証はありません。at least until the Swift ABI is finalizedいくつかの関連する問題は、スウィフトバグトラッカーで開いあります

はまた、あなたがConfigDataの配列をしたい場合は、あなたがすべきことに注意してくださいSwiftは配列要素の間にパディングを含めることができるので、サイズを測定するにはMemoryLayout<ConfigData>.strideを使用してください(再び、pエラー)。 ConfigDataの両方のレイアウトが16のストライドを持つことがわかります。

構造体のバイトレイアウトが気になる場合は、おそらくcompiler extensionsを使用してCで定義する必要がありますまたは挿入しないでください)。

2

私が間違って

NO、間違って何もやっているものはあります。あなたはちょうどアライメントを知る必要があります。

スウィフトコンパイラは、メンバーを4バイト境界に整列させています。ご存じのように、UInt8は1バイトしかかかりません。 xは、以下のメンバーを揃えるためにパディングバイトを意味

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

:だから、あなたの最初のConfigDataは、次のようにメモリ(*)で表されます。

そして、あなたの第二ConfigDataで、内部表現は次のようになります。後者の場合には

MemoryLayout<ConfigData>.sizeは、非整列バイトを末尾にカウントされません。そこにはいくつかのバイト変数が割り当てられます。

しかし、あなたは、アレイ内の複数のConfigDataを割り当てる場合は、スウィフトは一番下にパディングバイトを追加します。したがって、MemoryLayout<ConfigData>.strideは、この目的のためのカウントを返します。16は両方ともConfigDataです。

(*)スウィフトは、構造体のメンバーの割り当てを保証するものではありません。 ABIの安定性が明らかになるまで、詳細は将来変更される可能性があります。


私は遅刻していますが、私の答えは、ロブマオフの答えの一部を示しています。注意深くお読みください。

関連する問題