This is one of those areas where you just need to say "no".

Bitfields are handy when you need to access fields easily and don't need to know
or care exactly what bits the compiler uses for the purpose. But if
compatibility and portability are important to you, DO NOT use bitfields.

Compilers are perfectly free to choose any bits they want when laying out a
struct. There's nothing even processor-dependent about it. Different compilers
on the same platform may layout the same struct differently.

If you want to make sure you're accessing the same bits regardless of compiler
and platform, do the bit accessing yourself. For example, instead of:

     typedef struct
     {
          int  field1:3;
          int  field2:5;
     } mystruct1;

     void UseIt (int)
     {
     }

     static void Test1 (void)
     {
          mystruct1 st;

          st.field1 = 3;
          st.field2 = 12;

          UseIt (st.field1);
          UseIt (st.field2);
     }

Use:

     typedef struct
     {
          int  packed_field;
     } mystruct2;

     #define FIELD_GET(s, sh, m) ((((s).packed_field) >> sh) & m)
     #define FIELD_SET(s, v, sh, m) \
          (s).packed_field = (((s).packed_field & ~(m << sh)) | (((v) & m) <<
sh))

     #define FIELD1_SHIFT 5
     #define FIELD1_MASK 0x7UL
     #define FIELD1_GET(s) FIELD_GET(s, FIELD1_SHIFT, FIELD1_MASK)
     #define FIELD1_SET(s, v) FIELD_SET(s, v, FIELD1_SHIFT, FIELD1_MASK)

     #define FIELD2_SHIFT 0
     #define FIELD2_MASK 0x1FUL
     #define FIELD2_GET(s) FIELD_GET(s, FIELD2_SHIFT, FIELD2_MASK)
     #define FIELD2_SET(s, v) FIELD_SET(s, v, FIELD2_SHIFT, FIELD2_MASK)

     static void Test2 (void)
     {
          mystruct2 st;

          FIELD1_SET (st, 3);
          FIELD2_SET (st, 12);

          UseIt (FIELD1_GET (st));
          UseIt (FIELD2_GET (st));
     }

This is just off the top of my head, so there may be some bugs (for instance, if
any of those bits fields are *signed*, you'll need to make sure the extracted
values are extended as necessary).  But you get the idea.

-- Keith Rollin
-- Palm OS Emulator engineer






Jason Freund <[EMAIL PROTECTED]> on 01/05/2000 10:56:21 PM

Please respond to [EMAIL PROTECTED]

Sent by:  Jason Freund <[EMAIL PROTECTED]>


To:   [EMAIL PROTECTED]
cc:    (Keith Rollin/HQ/3Com)
Subject:  Bitfield ordering




Hi,

I don't use linux for development anymore, but I used to have to reverse the
order of bitfields when creating targets for PC(Linux) and PalmPilot, like
so:

struct {
#ifdef  i386
    uchar field1: 3;
    uchar field2: 5;
#else
    uchar field2: 5;
    uchar field1: 3;
#endif
}

Now I moved to Widows and use CW and  VisualC++, and it seems like you no
longer need to reverse the bitfields in order to make the data compatible.

I use bitfields all over the place, and removing the ifdefs fixed the one
case I looked at in my code.  But as a sanity check, I'd like to know if
anyone else has experienced the nuances of using bitfields on different
platforms to know if this is the case.

-Jason






Reply via email to