This issue tracker has been migrated to GitHub, and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

classification
Title: struct module: pack/unpack and byte order on x86_64
Type: behavior Stage:
Components: Library (Lib) Versions: Python 3.0, Python 3.1, Python 2.7, Python 2.6
process
Status: closed Resolution: not a bug
Dependencies: Superseder:
Assigned To: Nosy List: pitrou, termim
Priority: normal Keywords:

Created on 2008-11-06 17:30 by termim, last changed 2022-04-11 14:56 by admin. This issue is now closed.

Messages (2)
msg75569 - (view) Author: Mikhail Terekhov (termim) * Date: 2008-11-06 17:30
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.
msg78388 - (view) Author: Antoine Pitrou (pitrou) * (Python committer) Date: 2008-12-27 23:07
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.
History
Date User Action Args
2022-04-11 14:56:41adminsetgithub: 48520
2008-12-27 23:07:55pitrousetstatus: open -> closed
resolution: not a bug
messages: + msg78388
nosy: + pitrou
versions: + Python 2.6, Python 3.0, Python 3.1, Python 2.7, - Python 2.5
2008-11-06 17:30:43termimcreate