1

I have to create union that would allow me to get (and display) every single bit from a particular byte. Does that even make sense? I think i know how to do that with bitwise operators, but no idea how to use unions for the same effect.

flwn
  • 129
  • 1
  • 1
  • 7

4 Answers4

2

It is recommended to use bitwise operations. You can combine union and bit-fields to extract bits too, but note, this is endianness-dependent, which is why this is not recommended, a sample here for your learning though:

#include <stdio.h>
#include <string.h>

union Bits {
    char b;
    struct bits {
#ifdef LITTLE_ENDIAN
            unsigned int b0: 1;
            unsigned int b1: 1;
            unsigned int b2: 1;
            unsigned int b3: 1;
            unsigned int b4: 1;
            unsigned int b5: 1;
            unsigned int b6: 1;
            unsigned int b7: 1;
#else
            // reverse the order of the bit fields.
#endif
    } bits;
};

int main(void) {
    char a = 'A';
    union Bits b;
    b.b = a;

    printf("0x%x\n", a);
    printf("%d%d%d%d%d%d%d%d\n", b.bits.b7, b.bits.b6, b.bits.b5, b.bits.b4, b.bits.b3, b.bits.b2, b.bits.b1, b.bits.b0);

    return 0;
}

This should output

0x41
01000001
fluter
  • 13,238
  • 8
  • 62
  • 100
  • No. You can not state which order bit-fields will be. The order of bit-fields is implementation-defined. Per **6.7.2.1 Structure and union specifiers**, paragraph 11 of the [C Standard](http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1570.pdf): "... The order of allocation of bit-fields within a unit (high-order to low-order or low-order to high-order) is implementation-defined. ..." – Andrew Henle Apr 16 '16 at 15:33
  • It is implementation-defined, that's why I said it depends on endianness and not portable, I never said one can state the order of bit field. :) – fluter Apr 16 '16 at 15:35
  • It doesn't only depend on endianness - different compilers can and do treat bit-fields differently. So you can't really know which bit is which. Some of them even screw it up: https://lwn.net/Articles/478657/ – Andrew Henle Apr 16 '16 at 15:42
  • You are correct, one should not reply on the order of bit field, the standard does not make such guarantee. – fluter Apr 16 '16 at 15:49
  • I wrote "unsigned char" instead if "unsigned int" and it worked for me. – Sunny127 Nov 14 '18 at 15:09
1

You can use a union of a unit8_t and a struct containing 8 one-bit bitfields. However, even though that will give you access to individual bits, you won't know which bits they are! That will depend on how your compiler assigns the bit fields to the underlying byte, which can depend on the endianness of your target machine.

See this SO Q&A.

Community
  • 1
  • 1
Doug Currie
  • 40,708
  • 1
  • 95
  • 119
1

Since C99, we have anonymous structures and unions, making things easier:

#include <stdio.h>
#include <stdbool.h>
#include <inttypes.h>

union disByte
{
    uint8_t byte;
    // Assuming little endian
    struct {
        bool b0: 1;
        bool b1: 1;
        bool b2: 1;
        bool b3: 1;
        bool b4: 1;
        bool b5: 1;
        bool b6: 1;
        bool b7: 1;
    };
};

int main()
{
    union disByte foo;
    foo.byte = 42;
    printf("%d %d %d %d %d %d %d %d\n", foo.b0, foo.b1, foo.b2, foo.b3, foo.b4, foo.b5, foo.b6, foo.b7);
}

However, bit manipulation is usually preferred (Your question has been tagged "bit-manipulation").

#define XTH_BIT_OF(NUM, X) (bool)(NUM & (1U << X))

The advantages of using bit manipulation are:

  1. You don't need to worry about endianness.
  2. It looks shorter and clearer.
nalzok
  • 14,965
  • 21
  • 72
  • 139
1

You can use a bit field and an union to do this like this:

#include <stdio.h>


typedef union {
        struct {
            unsigned int:0;
            unsigned int firstBit : 1;
            unsigned int secondBit : 1;
            unsigned int thirdBit : 1;
            unsigned int fourthBit : 1;
            unsigned int fifthBit : 1;
            unsigned int sixthBit : 1;
            unsigned int seventhBit : 1;
            unsigned int eigthBit : 1;
        };
        int raw;
} bitsOfByte;

int main()
{
bitsOfByte dt;
dt.raw = 254;
printf("Bits are %d/%d/%d/%d/%d/%d/%d/%d", dt.firstBit, dt.secondBit, dt.thirdBit, dt.fourthBit, dt.fifthBit, dt.sixthBit, dt.seventhBit, dt.eigthBit);
return 0;
}

Note that in this implementation, the first bit is the lower-bit

AdminXVII
  • 1,319
  • 11
  • 22