I try to unpack a list of values from bytes. I want to read and unpack them together but i meet this thing...
When we calculate a size of concatenated string fmt we get one result, if we calculate a size of all parts of string fmt and sum them, we get another result (expected result).
from struct import calcsize
f0 = '3B'
f1 = '2H'
f2 = '1B'
f3 = '4H'
f4 = '2B'
print(calcsize(f0) + calcsize(f1) + calcsize(f2) + calcsize(f3) + calcsize(f4))
# 18 (expected)
print(calcsize(f0 + f1 + f2 + f3 + f4))
# 20 (what?!! o_O)
May be I does not understand something?
1 Answer 1
In "native" byte order (the default), the struct module applies the same padding rules as C does to its structures. So a padding byte occurs between 3B and 2H (because H is two byte aligned), and another between 1B and 4H.
Per the docs:
Note: By default, the result of packing a given C struct includes pad bytes in order to maintain proper alignment for the C types involved; similarly, alignment is taken into account when unpacking. This behavior is chosen so that the bytes of a packed struct correspond exactly to the layout in memory of the corresponding C struct. To handle platform-independent data formats or omit implicit pad bytes, use
standardsize and alignment instead ofnativesize and alignment: see Byte Order, Size, and Alignment for details.
So just use a non-default size/alignment to "fix" this if appropriate.