Why do mix types in Python struct.pack use more space than necessary?

I just tried using struct.pack in Python for the first time and I don't understand its behavior when I mix types

When I try to pack a single char and nothing else, it works as expected, i.e.

struct.pack("b",1) 

gives '\x01' . But as soon as I try to mix data of another type, the char fills as long as this type, for example

 struct.pack("bi",1,1) 

gives '\x01\x00\x00\x00\x01\x00\x00\x00' .

Is this standard behavior and why? Is there any way around this?

Edit

Simply put:

 >>> struct.calcsize("b") 1 >>> struct.calcsize("i") 4 >>> struct.calcsize("bi") 8 
+6
source share
4 answers

struct.pack usually used to access memory structures, not files. In memory, accessing data that takes up several bytes at an odd / uneven address can cause exceptions or performance loss.

This is why compilers align data (usually at the border of 4 or 8 bytes) and the struct module in Python does the same.

To disable this, you can use the first character of the format string to specify the order and byte order. In your case, try struct.pack("=bi",1,1)

If you do not specify anything, then an implicit @ , which means "native byte order, size and alignment". See the documentation for other parameters .

+8
source

Yes it is.

By default, C types are represented in the native machine format and byte order and are correctly aligned by skipping the missing bytes, if necessary (in accordance with the rules used by the C compiler).

If you don't want alignment, just specify the byte order by starting the format string with '=' , '<' or '>' (same as '!' ).

+4
source

From the manual:

By default, the result of packing this C structure includes bytes in bytes to maintain proper alignment for the involved C types; Similarly, alignment is taken into account when unpacking. This behavior is chosen so that the bytes of the packed structure exactly match the layout in the memory of the corresponding structure C.

i is a 4-byte integer to be placed in a proper word. That way, something near him that doesn't fill out the word will be complemented to do this. You can override this behavior by specifying the byte order without proper alignment.

That is why - with more complex structures - the ordering of things within things is many.

See also the Wikipedia article on this topic.

+2
source

See the documentation for the structure ; in particular, it says:

By default, the result of packing this C structure includes bytes in bytes to maintain proper alignment for the involved C types; Similarly, alignment is taken into account when unpacking. This behavior is chosen so that the bytes of the packed structure exactly match the layout in the memory of the corresponding structure C.

And see, for example, this question for C: C struct memory layout?

In short, an integer is 4 bytes, and therefore it should start with a multiple of 4. If you change the order of b and I'm around, the problem will not arise.

+2
source

All Articles