Eryk Sun added the comment: > I would strongly argue to generally prohibit this > with an exception
I agree. A warning in the tutorial isn't sufficient. ctypes should raise an error when setting a union or bitfield struct type in argtypes or when passing one by value. Here's some background to flesh out this issue. Both struct and union types are defined as the libffi type FFI_TYPE_STRUCT (13), since FFI_TYPE_UNION doesn't exist. class MyUnion(ctypes.Union): _fields_ = [("x%s" % i, ctypes.c_double) for i in range(11)] >>> stgdict(MyUnion).length 11 >>> stgdict(MyUnion).ffi_type_pointer size: 8 alignment: 8 type: 13 elements: 17918992 >>> (ctypes.c_void_p * 12).from_address(17918992)[:] [140354450953784, 140354450953784, 140354450953784, 140354450953784, 140354450953784, 140354450953784, 140354450953784, 140354450953784, 140354450953784, 140354450953784, 140354450953784, None] >>> ffi_type.from_address(140354450953784) size: 8 alignment: 8 type: 3 elements: LP_LP_ffi_type(<NULL>) Type 3 is FFI_TYPE_DOUBLE. class MyStruct(ctypes.Structure): _fields_ = [("x%s" % i, ctypes.c_double) for i in range(11)] >>> stgdict(MyStruct).length 11 >>> stgdict(MyStruct).ffi_type_pointer size: 88 alignment: 8 type: 13 elements: 17868096 >>> (ctypes.c_void_p * 12).from_address(17868096)[:] [140354450953784, 140354450953784, 140354450953784, 140354450953784, 140354450953784, 140354450953784, 140354450953784, 140354450953784, 140354450953784, 140354450953784, 140354450953784, None] As shown above, FFI_TYPE_STRUCT uses the `elements` array in its ffi_type. Each element is a pointer to an ffi_type for the corresponding field in the struct or union. This array is terminated by a NULL pointer. The C data size of a MyUnion instance is 8 bytes. This is less than 32 bytes (i.e. four 8-byte words), so the code in classify_argument rightfully assumes the argument won't be passed on the stack. Thus it classifies the register type(s) to use, presuming it's dealing with a struct. But since it's a union the total size of the elements is unrelated to the union's size. libffi would need to implement an FFI_TYPE_UNION type to support this as a separate case. Otherwise ctypes needs to actively forbid passing a union by value. ---------- nosy: +eryksun versions: +Python 3.6 _______________________________________ Python tracker <rep...@bugs.python.org> <http://bugs.python.org/issue26628> _______________________________________ _______________________________________________ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com