Question

There are several times in C in which a type is guaranteed to be at LEAST a certain size, but not necessarily exactly that size (sizeof(int) can result in 2 or 4). However, I need to be absolutely certain of some sizes and memory locations. If I have a union such as below:

typedef union{
    struct{
        unsigned int a:1, b:1, c:1, d:1, e:1, f:1, g:1, h:1;
    };   
    unsigned int val:8;
} foo;

Is it absolutely guaranteed that the value of val is 8 bits long? Moreover, is it guaranteed that a is the most significant bit of val, and b is the second-most significant bit? I wish to do something like this:

foo performLogicalNOT(foo x){
    foo product;
    product.val = ~x.val;
    return product;
}

And thus with an input of specific flags, return a union with exactly the opposite flags (11001100 -> 00110011). The actual functions are more complex, and require that the size of val be exactly 8. I also want to perform AND and OR in the same manner, so it is crucial that each a and b value be where I expect them to be and the size I expect them to be.

Was it helpful?

Solution

How the bits would be packed are not standard and pretty much implementation defined. Have a look at this answer.

Instead of relying on Union, it is better to use bitmask to derive the values. For the above example, char foo can be used. All operations (like ~) would be done on foo only. To get or set the bit specific values, appropriate bitmask can be used.

#define BITMASK_A  0x80
#define BITMASK_B  0x40

and so on..

To get the value of 'a' bit, use:

foo & BITMASK_A

To set the bit to 1, use:

foo | BITMASK_A

To reset the bit to 0, use:

foo & (~BITMASK_A)
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top