I was pondering (and therefore am looking for a way to learn this, and not a better solution) if it is possible to get an array of bits in a structure.
Let me demonstrate by an example. Imagine such a code:
#include <stdio.h> struct A { unsigned int bit0:1; unsigned int bit1:1; unsigned int bit2:1; unsigned int bit3:1; }; int main() { struct A a = {1, 0, 1, 1}; printf("%u\n", a.bit0); printf("%u\n", a.bit1); printf("%u\n", a.bit2); printf("%u\n", a.bit3); return 0; }
In this code, we have 4 individual bits packed in a struct. They can be accessed individually, leaving the job of bit manipulation to the compiler. What I was wondering is if such a thing is possible:
#include <stdio.h> typedef unsigned int bit:1; struct B { bit bits[4]; }; int main() { struct B b = {{1, 0, 1, 1}}; for (i = 0; i < 4; ++i) printf("%u\n", b.bits[i]); return 0; }
I tried declaring bits
in struct B
as unsigned int bits[4]:1
or unsigned int bits:1[4]
or similar things to no avail. My best guess was to typedef unsigned int bit:1;
and use bit
as the type, yet still doesn't work.
My question is, is such a thing possible? If yes, how? If not, why not? The 1 bit unsigned int is a valid type, so why shouldn't you be able to get an array of it?
Again, I don't want a replacement for this, I am just wondering how such a thing is possible.
P.S. I am tagging this as C++, although the code is written in C, because I assume the method would be existent in both languages. If there is a C++ specific way to do it (by using the language constructs, not the libraries) I would also be interested to know.
UPDATE: I am completely aware that I can do the bit operations myself. I have done it a thousand times in the past. I am NOT interested in an answer that says use an array/vector instead and do bit manipulation. I am only thinking if THIS CONSTRUCT is possible or not, NOT an alternative.
Update: Answer for the impatient (thanks to neagoegab):
Instead of
typedef unsigned int bit:1;
I could use
typedef struct { unsigned int value:1; } bit;
properly using #pragma pack
No, you can't. Bit field can only be used with integral type variables.
It stores bits using an array of type int (each element in the array usually represents 32 bits).
This is a C Program to implement Bit Array. A bit array is an array data structure that compactly stores bits. It can be used to implement a simple set data structure. A bit array is effective at exploiting bit-level parallelism in hardware to perform operations quickly.
5) Array of bit fields is not allowed. For example, the below program fails in the compilation.
NOT POSSIBLE - A construct like that IS NOT possible(here) - NOT POSSIBLE
One could try to do this, but the result will be that one bit is stored in one byte
#include <cstdint> #include <iostream> using namespace std; #pragma pack(push, 1) struct Bit { //one bit is stored in one BYTE uint8_t a_:1; }; #pragma pack(pop, 1) typedef Bit bit; struct B { bit bits[4]; }; int main() { struct B b = {{0, 0, 1, 1}}; for (int i = 0; i < 4; ++i) cout << b.bits[i] <<endl; cout<< sizeof(Bit) << endl; cout<< sizeof(B) << endl; return 0; }
output:
0 //bit[0] value 0 //bit[1] value 1 //bit[2] value 1 //bit[3] value 1 //sizeof(Bit), **one bit is stored in one byte!!!** 4 //sizeof(B), ** 4 bytes, each bit is stored in one BYTE**
In order to access individual bits from a byte here is an example (Please note that the layout of the bitfields is implementation dependent)
#include <iostream> #include <cstdint> using namespace std; #pragma pack(push, 1) struct Byte { Byte(uint8_t value): _value(value) { } union { uint8_t _value; struct { uint8_t _bit0:1; uint8_t _bit1:1; uint8_t _bit2:1; uint8_t _bit3:1; uint8_t _bit4:1; uint8_t _bit5:1; uint8_t _bit6:1; uint8_t _bit7:1; }; }; }; #pragma pack(pop, 1) int main() { Byte myByte(8); cout << "Bit 0: " << (int)myByte._bit0 <<endl; cout << "Bit 1: " << (int)myByte._bit1 <<endl; cout << "Bit 2: " << (int)myByte._bit2 <<endl; cout << "Bit 3: " << (int)myByte._bit3 <<endl; cout << "Bit 4: " << (int)myByte._bit4 <<endl; cout << "Bit 5: " << (int)myByte._bit5 <<endl; cout << "Bit 6: " << (int)myByte._bit6 <<endl; cout << "Bit 7: " << (int)myByte._bit7 <<endl; if(myByte._bit3) { cout << "Bit 3 is on" << endl; } }
In C++ you use std::bitset<4>
. This will use a minimal number of words for storage and hide all the masking from you. It's really hard to separate the C++ library from the language because so much of the language is implemented in the standard library. In C there's no direct way to create an array of single bits like this, instead you'd create one element of four bits or do the manipulation manually.
EDIT:
The 1 bit unsigned int is a valid type, so why shouldn't you be able to get an array of it?
Actually you can't use a 1 bit unsigned type anywhere other than the context of creating a struct/class member. At that point it's so different from other types it doesn't automatically follow that you could create an array of them.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With