You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
ctypes: bitfield lost data with union on linux platform #95496
fromctypesimportStructure,Unionfromctypesimportalignment,sizeoffromctypesimportc_int8,c_int16,c_int32,c_int64fromctypesimportc_uint8,c_uint16,c_uint32,c_uint64classsub_type(Structure):
_fields_= [
('a',c_uint8,4),
('b',c_uint8,4),
('c',c_uint16,10),
('d',c_uint16,10),
('e',c_uint8,1),
('f',c_uint8,1),
('g',c_uint8,1),
]
classmain_type(Union):
byte_length=sizeof(sub_type)
_fields_= [
("data", sub_type),
("asbytes", c_uint8*byte_length),
]
a=main_type(data=sub_type(e=1,f=1,g=1))
print(list(a.asbytes))
#on windows, print value is correct#[0, 0, 0, 0, 0, 0, 7, 0]#on linux, the value is wrong at all. the length is correct, but value is wrong.#[0, 0, 0, 0, 0, 0]
This is fixed in #97702 and related fixes. Should be released in Python 3.14; unfortunately the fix is backwards-incompatible so I don't plan to backport it.
Note that bitfields use a different layout on Linux (gcc/sysV): the output will be [0, 0, 0, 0, 0, 28]. But the values are in the proper place:
fornamein'abcdefg':
print(name, getattr(a.data, name))
# → zeros for abce, ones for efg
To get the Windows behaviour you can add _layout_ = 'ms' to TestStruct. (The mechanism might still change before the 3.14.0 final release; see Structure docs for current docs.)
Activity
korjaa commentedon Sep 1, 2022
I get similar error without unions. Below is a test snippet that passes on Windows but fails on Ubuntu WSL2.
I get following output in WSL2 Ubuntu
I tried Python 3.9 on WSL2 Ubuntu too with same result.
px528 commentedon Sep 1, 2022
encukou commentedon Jan 17, 2025
This is fixed in #97702 and related fixes. Should be released in Python 3.14; unfortunately the fix is backwards-incompatible so I don't plan to backport it.
Note that bitfields use a different layout on Linux (gcc/sysV): the output will be
[0, 0, 0, 0, 0, 28]. But the values are in the proper place:To get the Windows behaviour you can add
_layout_ = 'ms'toTestStruct. (The mechanism might still change before the 3.14.0 final release; see Structure docs for current docs.)px528 commentedon Jan 17, 2025