Vlad Riscutia <riscutiav...@gmail.com> added the comment:

I took a look at this and I believe behavior is correct on Windows, the issue 
is with the test. For example this test is failing:

class closest_fit(ctypes.BigEndianStructure):
    _pack_      = 1    # aligned to 8 bits, not ctypes default of 32
    _fields_    = [
                   ("Data0",   ctypes.c_uint32, 32),
                   ("Data1",   ctypes.c_uint8, 3),
                   ("Data2",   ctypes.c_uint16, 12),
                  ]

But you also have this assumption when generating the test data:

size_of_structures_in_bytes = 6

I verified and this does not hold with MSVC compiler. Using VC++ 2005, this code

typedef struct Test {
        unsigned int x: 32; // uint_32 : 32
        unsigned char y: 3; // uint_8 : 3
        unsigned short int z: 12; // uint_16 : 12
} Test;

gives sizeof(Test) == 7. In Python, if you look at sizeof(closest_fit), it will 
also be 7.

Looking at cfield.c, seems this was taken into account when creating bit fields:

    if (bitsize /* this is a bitfield request */
        && *pfield_size /* we have a bitfield open */
#ifdef MS_WIN32
        /* MSVC, GCC with -mms-bitfields */
        && dict->size * 8 == *pfield_size
#else
        /* GCC */
        && dict->size * 8 <= *pfield_size
#endif
        && (*pbitofs + bitsize) <= *pfield_size) {
        /* continue bit field */
        fieldtype = CONT_BITFIELD;
#ifndef MS_WIN32
    } else if (bitsize /* this is a bitfield request */
        && *pfield_size /* we have a bitfield open */
        && dict->size * 8 >= *pfield_size
        && (*pbitofs + bitsize) <= dict->size * 8) {
        /* expand bit field */
        fieldtype = EXPAND_BITFIELD;
#endif
    } else if (bitsize) {
        /* start new bitfield */
        fieldtype = NEW_BITFIELD;
        *pbitofs = 0;
        *pfield_size = dict->size * 8;
 
Though I don't know this first-hand, above code plus sizeof experiment leads me 
to believe that gcc packs bitfields differently than MSVC. Seems that gcc will 
expand existing bitfield trying to pack structure more tightly so indeed on 
Linux (or I assume Windows gcc build), size of this structure is 6 as gcc will 
combine these seeing that an unsigned short can hold all 15 bits required but 
with MSVC this won't work. MSVC will allocate both the c_uint8 and the c_uint16 
once is sees that last 12 bits don't fit in remaining c_uint8.

As far as I can tell this is by design and Python matches expected MSVC 
structure packing for this test case.

----------
nosy: +vladris

_______________________________________
Python tracker <rep...@bugs.python.org>
<http://bugs.python.org/issue6069>
_______________________________________
_______________________________________________
Python-bugs-list mailing list
Unsubscribe: 
http://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com

Reply via email to