Order of fields when using a bit field in C

后端 未结 4 2113
广开言路
广开言路 2020-11-30 12:53

I have a struct of the following type

typedef struct
{
unsigned int a : 8;
unsigned int b : 6;
unsigned int c : 2;
}x, *ptr;

What i would l

相关标签:
4条回答
  • 2020-11-30 13:16

    You set a C structure to raw bits at your peril.

    You know that the bits are and what they mean, so you can fill out the fields of the structure. Yes it's more code than memcpy, but it won't break if someone adds a field, and if helps enforce bit-level specificity at the communcations level.

    0 讨论(0)
  • 2020-11-30 13:18

    C standard allows compiler to put bit-fields in any order. There is no reliable and portable way to determine the order.

    If you need to know the exact bit positions, it is better use plain unsigned variable and bit masking.

    Here's one possible alternative to using bit-fields:

    #include <stdio.h>
    
    #define MASK_A    0x00FF
    #define MASK_B    0x3F00
    #define MASK_C    0xC000
    #define SHIFT_A   0
    #define SHIFT_B   8
    #define SHIFT_C   14
    
    unsigned GetField(unsigned all, unsigned mask, unsigned shift)
    {
        return (all & mask) >> shift;
    }
    
    unsigned SetField(unsigned all, unsigned mask, unsigned shift, unsigned value)
    {
        return (all & ~mask) | ((value << shift) & mask);
    }
    
    unsigned GetA(unsigned all)
    {
        return GetField(all, MASK_A, SHIFT_A);
    }
    
    unsigned SetA(unsigned all, unsigned value)
    {
        return SetField(all, MASK_A, SHIFT_A, value);
    }
    
    /* Similar functions for B and C here */
    
    int main(void)
    {
        unsigned myABC = 0;
        myABC = SetA(myABC, 3);
        printf("%u", GetA(myABC)); // Prints 3
    }
    
    0 讨论(0)
  • 2020-11-30 13:26

    memory always depends on the underlying machine structure (endianness) and on the strategy for packing/arranging the structure the compiler is performing.

    0 讨论(0)
  • 2020-11-30 13:27

    I know this is an old one, but I would like to add my thoughts.

    1. Headers in C are meant to be usable across objects, which means the compiler has to be somewhat consistent.

    2. In my experience I have always seen bitfields in LSB order. This will put the bits in MSB->LSB order of c:b:a

    The 16 bits, read in byte order is "00 40". Translated from Little-endian, this is a 16-bit value of 0x4000.

    This is:

    c == [15:14] == b'01
    b == [13:8] == 0
    a == [7:0] == 0
    
    0 讨论(0)
提交回复
热议问题