Bit Fields in C
In C, we can specify size (in bits) of structure and union members. The idea is to use memory efficiently when we know that the value of a field or group of fields will never exceed a limit or is withing a small range.
For example, consider the following declaration of date without use of bit fields.
Output:
Output:
1) A special unnamed bit field of size 0 is used to force alignment on next boundary. For example consider the following program.
Output:
2) We cannot have pointers to bit field members as they may not start at a byte boundary.
Output:
3) It is implementation defined to assign an out-of-range value to a bit field member.
Output:
4) In C++, we can have static members in a structure/class, but bit fields cannot be static.
5) Array of bit fields is not allowed. For example, the below program fails in compilation.
Output:
For example, consider the following declaration of date without use of bit fields.
#include <stdio.h>// A simple representation of datestruct date{ unsigned int d; unsigned int m; unsigned int y;};int main(){ printf("Size of date is %d bytes\n", sizeof(struct date)); struct date dt = {31, 12, 2014}; printf("Date is %d/%d/%d", dt.d, dt.m, dt.y);} |
Size of date is 12 bytes Date is 31/12/2014The above representation of ‘date’ takes 12 bytes on a compiler where an unsigned int takes 4 bytes. Since we know that the value of d is always from 1 to 31, value of m is from 1 to 12, we can optimize the space using bit fields.
#include <stdio.h>// A space optimized representation of datestruct date{ // d has value between 1 and 31, so 5 bits // are sufficient unsigned int d: 5; // m has value between 1 and 12, so 12 bits // are sufficient unsigned int m: 4; unsigned int y;};int main(){ printf("Size of date is %d bytes\n", sizeof(struct date)); struct date dt = {31, 12, 2014}; printf("Date is %d/%d/%d", dt.d, dt.m, dt.y); return 0;} |
Size of date is 8 bytes Date is 31/12/2014Following are some interesting facts about bit fields in C.
1) A special unnamed bit field of size 0 is used to force alignment on next boundary. For example consider the following program.
#include <stdio.h>// A structure without forced alignmentstruct test1{ unsigned int x: 5; unsigned int y: 8;};// A structure with forced alignmentstruct test2{ unsigned int x: 5; unsigned int: 0; unsigned int y: 8;};int main(){ printf("Size of test1 is %d bytes\n", sizeof(struct test1)); printf("Size of test2 is %d bytes\n", sizeof(struct test2)); return 0;} |
Size of test1 is 4 bytes Size of test2 is 8 bytes
2) We cannot have pointers to bit field members as they may not start at a byte boundary.
#include <stdio.h>struct test{ unsigned int x: 5; unsigned int y: 5; unsigned int z;};int main(){ test t; // Uncommenting the following line will make // the program compile and run printf("Address of t.x is %p", &t.x); // The below line works fine as z is not a // bit field member printf("Address of t.z is %p", &t.z); return 0;} |
error: attempt to take address of bit-field structure member 'test::x'
3) It is implementation defined to assign an out-of-range value to a bit field member.
#include <stdio.h>struct test{ unsigned int x: 2; unsigned int y: 2; unsigned int z: 2;};int main(){ test t; t.x = 5; printf("%d", t.x); return 0;} |
Implementation-Dependent
4) In C++, we can have static members in a structure/class, but bit fields cannot be static.
// The below C++ program compiles and runs finestruct test1 { static unsigned int x;};int main() { }// But below C++ program fails in compilation as bit fields// cannot be staticstruct test1 { static unsigned int x: 5;};int main() { }// error: static member 'x' cannot be a bit-field |
5) Array of bit fields is not allowed. For example, the below program fails in compilation.
struct test{ unsigned int x[10]: 5;};int main(){} |
error: bit-field 'x' has invalid type
No comments:
Post a Comment