Reputation: 8053
Why does a variable UInt8 in a swift struct show an offset of 2? However a struct of just UInt8s shows an offset of 1?
struct Test {
let a: UInt8
let b: UInt16
}
MemoryLayout<Test>.offset(of: \Test.a) // 0
MemoryLayout<Test>.offset(of: \Test.b) // 2 (not 1)
struct Test2 {
let a: UInt8
let b: UInt8
let c: UInt8
}
MemoryLayout<Test2>.offset(of: \Test2.a) // 0
MemoryLayout<Test2>.offset(of: \Test2.b) // 1
MemoryLayout<Test2>.offset(of: \Test2.c) // 2
Upvotes: 1
Views: 361
Reputation: 272760
This has to do with how Swift aligns your properties in memory. For your first struct, the alignment
is 2, whereas your second struct has an alignment of 1.
Your properties in Test
are not stored in memory all packed together like this:
x y y
where x
represents a byte for a
, and y
represents a byte for b
.
It looks more like this:
x y y
Notice the padding after x
.
The point I am trying to make here is that Swift divides up a part of memory into "slices" to put the properties of your structs in. These equal slices has to be able to contain all your properties. This is why in Test
, the memory has to be cut up into slices of 2 bytes, to fit in a UInt16
.
In Test2
however, cutting up the memory into slices of 1 byte is enough to contain UInt8
s.
This "How many bytes per slice" number is the alignment
.
For why Swift cuts memory up this way, read this.
Upvotes: 1