Issue 4270: struct module: pack/unpack and byte order on x86_64 (original) (raw)
pack/unpack behavior changes unexpectedly depending on the byte order:
l:/tmp >uname -pmiovs Linux #1 SMP 2008-10-14 22:17:43 +0200 x86_64 x86_64 x86_64 GNU/Linux l:/tmp >python python Python 2.5.1 (r251:54863, Aug 1 2008, 00:35:20) [GCC 4.2.1 (SUSE Linux)] on linux2 Type "help", "copyright", "credits" or "license" for more information.
import struct import struct struct.pack(">L",0xdeadbeef) struct.pack(">L",0xdeadbeef) '\xde\xad\xbe\xef' struct.pack("L",0xdeadbeef) struct.pack("L",0xdeadbeef) '\xef\xbe\xad\xde\x00\x00\x00\x00' struct.pack("<L",0xdeadbeef) struct.pack("<L",0xdeadbeef) '\xef\xbe\xad\xde'
The length of the result above is 8 when no byte order is specified and 4 when it is.
Another example:
struct.pack("L",0xdeadbeef00000000) '\x00\x00\x00\x00\xef\xbe\xad\xde' struct.pack("<L",0xdeadbeef00000000) '\x00\x00\x00\x00' struct.pack("!L",0xdeadbeef00000000) '\x00\x00\x00\x00' struct.pack("!L",0x12345678deadbeef) '\xde\xad\xbe\xef' struct.pack("L",0x12345678deadbeef) '\xef\xbe\xad\xdexV4\x12'
Last results look strange.
The change in result length is actually normal. If you look at the doc for the struct module, the default size and byte order character is "@", which means "native byte order and native size". On x86-64 Linux, the "native" long size is 64 bits, so the result is 8 bytes long. When using one of {"<", ">", "!", "="}, you instead select the "standard" long size according to the struct module which is 32 bits.
I agree it can be surprising though.