This question already has answers here:
":" (colon) in C struct - what does it mean? [duplicate]
(3 answers)
Closed 9 years ago.
While looking through the source package for QEMU, I found in the exec.c file:
struct PhysPageEntry {
/* How many bits skip to next level (in units of L2_SIZE). 0 for a leaf. */
uint32_t skip : 6;
/* index into phys_sections (!skip) or phys_map_nodes (skip) */
uint32_t ptr : 26;
};
I was wondering what the : operator means. I could not find it in a list of syntax definitions for C.
This is a structure declared with bit fields and the structure members are called bit fields: A
bit field is set up with a structure declaration that labels each field and determines its width. The above definition causes PhysPageEntry to contain one 6-bit field and one 26 bit field members namely skip and ptr respectively. Its signature is
struct
{
type [member_name] : width ;
};
Here width is the number of bits in the bit-field. The width must be less than or equal to the bit width of the specified type.
struct PhysPageEntry declares two bit fields skip and ptr. This is basically to allow the struct to pack these odd lengths (in terms of bits) efficiently. If the author didn't do this, the struct would likely be 8 bytes long (on a 32-bit architecture).
It represents number of bits. It's mostly used for unions:
struct byte {
unsigned a : 1;
unsigned b : 1;
unsigned c : 1;
unsigned d : 1;
unsigned e : 1;
unsigned f : 1;
unsigned g : 1;
unsigned h : 1;
};
You can read this too for better understanding.
Its called a bitfield. Within a structure or union
declaration, this declares 'skip' to be a "bit field" of 6 bits width. They are to be used inside of structures. If it helped please vote as right!
Related
When using bitfields in C, I found out differences I did not expect related to the actual type that is used to declare the fields.
I didn't find any clear explanation. Now, the problem is identified, so if though there is no clear response, this post may be useful to anyone facing the same issue.
Still if some can point to a formal explanation, this coudl be great.
The following structure, takes 2 bytes in memory.
struct {
char field0 : 1; // 1 bit - bit 0
char field1 : 2; // 2 bits - bits 2 down to 1
char field2 ; // 8 bits - bits 15 down to 8
} reg0;
This one takes 4 bytes in memory, the question is why ?
struct {
int field0 : 1; // 1 bit - bit 0
int field1 : 2; // 2 bits - bits 2 down to 1
char field2 ; // 8 bits - bits 15 down to 8
} reg1;
In both cases, the bits are organized in memory in the same way: field 2 is always taking bits 15 down to 8.
I tried to find some literarure on the subject, but still can't get a clear explanation.
The two most appropriate links I can found are:
http://www.catb.org/esr/structure-packing/
http://www.msg.ucsf.edu/local/programs/IBM_Compilers/C:C++/html/language/ref/clrc03defbitf.htm
However, none really explains really why the second structure is taking 4 bytes. Actually reading carefully, I would even expect the structure to take 2 bytes.
In both cases,
field0 takes 1 bit
field1 takes 2 bits
field2 takes 8 bits, and is aligned on the first available byte address
Hence, the useful data requires 2 bytes in both cases.
So what is behind the scene that makes reg1 to take 4 bytes ?
Full Code Example:
#include "stdio.h"
// Register Structure using char
typedef struct {
// Reg0
struct _reg0_bitfieldsA {
char field0 : 1;
char field1 : 2;
char field2 ;
} reg0;
// Nextreg
char NextReg;
} regfileA_t;
// Register Structure using int
typedef struct {
// Reg1
struct _reg1_bitfieldsB {
int field0 : 1;
int field1 : 2;
char field2 ;
} reg1;
// Reg
char NextReg;
} regfileB_t;
regfileA_t regsA;
regfileB_t regsB;
int main(int argc, char const *argv[])
{
int* ptrA, *ptrB;
printf("sizeof(regsA) == %-0d\n",sizeof(regsA)); // prints 3 - as expected
printf("sizeof(regsB) == %-0d\n",sizeof(regsB)); // prints 8 - why ?
printf("\n");
printf("sizeof(regsA.reg0) == %-0d\n",sizeof(regsA.reg0)); // prints 2 - as epxected
printf("sizeof(regsB.reg0) == %-0d\n",sizeof(regsB.reg1)); // prints 4 - int bit fields tells the struct to use 4 bytes then.
printf("\n");
printf("addrof(regsA.reg0) == 0x%08x\n",(int)(®sA.reg0)); // 0x0804A028
printf("addrof(regsA.reg1) == 0x%08x\n",(int)(®sA.NextReg)); // 0x0804A02A = prev + 2
printf("addrof(regsB.reg0) == 0x%08x\n",(int)(®sB.reg1)); // 0x0804A020
printf("addrof(regsB.reg1) == 0x%08x\n",(int)(®sB.NextReg)); // 0x0804A024 = prev + 4 - my register is not at the righ place then.
printf("\n");
regsA.reg0.field0 = 1;
regsA.reg0.field1 = 3;
regsA.reg0.field2 = 0xAB;
regsB.reg1.field0 = 1;
regsB.reg1.field1 = 3;
regsB.reg1.field2 = 0xAB;
ptrA = (int*)®sA;
ptrB = (int*)®sB;
printf("regsA.reg0.value == 0x%08x\n",(int)(*ptrA)); // 0x0000AB07 (expected)
printf("regsB.reg0.value == 0x%08x\n",(int)(*ptrB)); // 0x0000AB07 (expected)
return 0;
}
When I first write the struct I expected to get reg1 to take only 2 bytes, hence the next register was at the offset = 2.
The relevant part of the standard is C11/C17 6.7.2.1p11:
An implementation may allocate any addressable storage unit large enough to hold a bit-field. If enough space remains, a bit-field that immediately follows another bit-field in a structure shall be packed into adjacent bits of the same unit. If insufficient space remains, whether a bit-field that does not fit is put into the next unit or overlaps adjacent units is implementation-defined. The order of allocation of bit-fields within a unit (high-order to low-order or low-order to high-order) is implementation-defined. The alignment of the addressable storage unit is unspecified.
that, in connection with C11/C17 6.7.2.1p5
A. bit-field shall have a type that is a qualified or unqualified version of _Bool, signed int, unsigned int, or some other implementation-defined type. It is implementation-defined whether atomic types are permitted.
and that you're using char means that there is nothing to discuss in general - for a specific implementation check the compiler manuals. Here's the one for GCC.
From the 2 excerpts it follows that an implementation is free to use absolutely whatever types it wants to to implement the bitfields - it could even use int64_t for both of these cases having the structure of size 16 bytes. The only thing a conforming implementation must do is to pack the bits within the chosen addressable storage unit if enough space remains.
For GCC on System-V ABI on 386-compatible (32-bit processors), the following stands:
Plain bit-fields (that is, those neither signed nor unsigned) always have non- negative values. Although they may have type char, short, int, long, (which can have negative values),
these bit-fields have the same range as a bit-field of the same size
with the corresponding unsigned type. Bit-fields obey the same
size and alignment rules as other structure and union members, with
the following additions:
Bit-fields are allocated from right to left (least to most significant).
A bit-field must entirely reside in a storage unit appropriate for its declared type. Thus a bit-field never crosses its unit boundary.
Bit-fields may share a storage unit with other struct/union members, including members that are not bit-fields. Of course,
struct members occupy different parts of the storage unit.
Unnamed bit-fields' types do not affect the alignment of a structure or union, although individual bit-fields' member offsets obey the
alignment constraints.
i.e. in System-V ABI, 386, int f: 1 says that the bit-field f must be within an int. If entire bytes of space remains, a following char within the same struct will be packed inside this int, even if it is not a bit-field.
Using this knowledge, the layout for
struct {
int a : 1; // 1 bit - bit 0
int b : 2; // 2 bits - bits 2 down to 1
char c ; // 8 bits - bits 15 down to 8
} reg1;
will be
1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
|a b b x x x x x|c c c c c c c c|x x x x x x x x|x x x x x x x x|
<------------------------------ int ---------------------------->
and the layout for
struct {
char a : 1; // 1 bit - bit 0
char b : 2; // 2 bits - bits 2 down to 1
char c ; // 8 bits - bits 15 down to 8
} reg1;
will be
1
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5
|a b b x x x x x|c c c c c c c c|
<---- char ----><---- char ---->
So there are tricky edge cases. Compare the 2 definitions here:
struct x {
short a : 2;
short b : 15;
char c ;
};
struct y {
int a : 2;
int b : 15;
char c ;
};
Because the bit-field must not cross the unit boundary, the struct x members a and b need to go to different shorts. Then there is not enough space to accommodate the char c, so it must come after that. And the entire struct must be suitably aligned for short so it will be 6 bytes on i386. The latter however, will pack a and b in the 17 lowest bits of the int, and since there is still one entire addressable byte left within the int, the c will be packed here too, and hence sizeof (struct y) will be 4.
Finally, you must really specify whether the int or char is signed or not - the default might be not what you expect! Standard leaves it up to the implementation, and GCC has a compile-time switch to change them.
This question already has answers here:
bit vector implementation of sets
(2 answers)
Closed 6 years ago.
In my C class we were given an assignment:
Write an interactive program (standard input/output). Define the new type set using typedef which can hold a set of integers in the range 0-127. The data structure has to be as efficient as possible in terms of storage (hint: working with bits). Also you need to define 6 global variables A,B,C,D,E,F of type set. All operations on sets in the program will be on these 6 variables.
This command read_set A,5,6,7,4,5,4,-1 will read user's input of integers while -1 means end of user's input. Other commands a user can use: print_set A - prints the set in increasing order, union_set A,B,C does union on 2 sets and saves the output in a third set, intersect_set A,B,C - determines the intersection of 2 sets and saves the output to a third set.
As far as I understand I need to use bit-fields. I could create a table of integers from 0-127. Then I could create the 6 variables A,B,C,D,E,F using set type definition and giving 128 bit-fields to each variable. Then if a user inputs 15 I would turn on the the bit which represents 15 in the data type. I'm really not sure if this is the way, because it's not clear to me how I would arrange bit-fields such that I can turn on exactly 15-th bit if I need to, I would need to convert somehow an integer to bit-field name... Also print_set prints the set in increasing order so how could I re-arrange bit-fields for this?
Really hope you have some ideas.
Yes, each of the sets called A, B, C, D, E and F is represented by a couple of unsigned long long integers like this:
typedef struct {
unsigned long long high;
unsigned long long low;
} Set;
See https://en.wikipedia.org/wiki/C_data_types
This gives you 128 bits of data in a Set (64 bits for the high numbers 64 to 127, and 64 bits for the low numbers 0 to 63).
Then you just need to do some bit manipulation like this: http://www.tutorialspoint.com/ansi_c/c_bits_manipulation.htm
For a number between 0 and 63, you'd shift 1 to the left x times and then set that bit on the "low" field.
For a number between 64 and 127, you'd shift 1 to the left x-64 times and then set that bit on the "high" field.
Hope this helps!
Using bitfields for this assignment will prove very cumbersome because of alignment issues, and you cannot define arrays of bitfields anyway. I would suggest using an array of bytes (unsigned char) and packing values into this array. A 7-bit value spanning at most 2 bytes.
The array for count values should be allocated with a size of (count + 7) / 8 bytes. In order to conserve space, you can store small sets in an integer and larger sets using an allocated array.
The datatype would look like:
#include <stdint.h>
#include <stdlib.h>
typedef struct set {
size_t count;
union {
uintptr_t v;
unsigned char *a;
};
} set;
Here is how to extract the n-th value:
int get_7bits(const set *s, size_t n) {
if (s == NULL || n >= s->count) {
return -1;
} else
if (n < sizeof(uintptr_t) * CHAR_BIT / 7) {
return (s->v >> (n * 7)) & 127;
} else {
size_t i = n / 7;
int shift = n % 7;
if (shift <= CHAR_BIT - 7) {
/* value fits in one byte */
return (s->a[i] >> shift) & 127;
} else {
/* value spans 2 bytes */
return ((s->a[i] | (s->a[i + 1] << CHAR_BIT)) >> shift) & 127;
}
}
}
You can write the other access functions and complete your assignment.
Here I have a code snippet.
#include <stdio.h>
int main()
{
struct value
{
int bit1 : 1;
int bit2 : 4;
int bit3 : 4;
} bit;
printf("%d",sizeof(bit));
return 0;
}
I'm getting the output as 4 (32 bit compiler).
Can anyone explain me how? Why is it not 1+ 4 + 4 = 9?
I've never worked with bit fields before so would love some help. Thank you. :)
When you tell the C compiler this:
int bit1 : 1
It interprets it as, and allocates to it, an integer; but refers to it's first bit as bit1.
So if we consider your code:
struct value
{
int bit1 : 1;
int bit2 : 4;
int bit3 : 4;
} bit;
What you are telling the compiler is this: Take necessary number of the ints, and refer to the chunks bit 1 as bit1, then refer to bits 2 - 5 as bit2, and then refer to bits 6 - 9 as bit3.
Since the complete number of bits required are 9, and an int is 32 bits (in your computer's architecture), memory space of only 1 int is required. Thus you get the size as 4 (bytes).
Instead, if you were to define the struct using chars, since char is 8 bits, the compiler would allocate the memory space of two chars for each struct value. And you will get 2 (bytes) as your output.
Because C requests to pack the bits in the same unit (here one signed int / unsigned int):
(C99, 6.7.2.1p10) "If enough space remains, a bit-field that immediately follows another bit-field in a structure shall be packed into adjacent bits of the same unit"
The processor just likes chucking around 32 bits in one go - not 9, 34 etc.
It just rounds it up to what the processor likes. (Keep the worker happy)
Hey all this is for C programming.
Here are the questions as they were presented to me, can someone tell me how I would correctly write code for the following statements in C? FYI i already answered this quiz but my professor won't post the answers himself. I did very poorly when he graded it, but to help make sense of this i will provide my answers (as incorrect as they are)
1: Create a structure that will hold bits the represent the following:
count: a 4 bit BCD number
red LED: 1 bit
green LED: 1 bit
motor direction: 2 bits
Name the structure motorStatus
Use typedef to name this new data type: mtrStatus_t
typedef unsigned char mtrStatus_t;
struct motorStatus mtrStatus_t {
mtrStatus_t count: 4;
mtrStatus_t redLED: 1;
mtrStatus_t greenLED: 1;
mtrStatus_t motorDirection: 2;
};
2: Create a new instance of the structure and name it motor1Status
motorStatus = motor1Status;
3: Write statements to initialize the new structure members as follows:
count: 9 BCD
red LED: 1
green LED: 0
Motor Direction: 10
count: 0x09;
redLED: 0x01;
greenLED: 0x00
motorDirection: 0x0A
For the first one I would do something like this:
typedef struct motorStatus
{
int count: 4;
int redLED: 1;
int greenLED: 1;
int motorDirection: 2;
} mtrStatus_t;
The second one is more like:
mtrStatus_t motor1status;
and finally:
motor1status.count = 0x9;
motor1status.redLED = 1;
motor1status.greenLED = 0;
motor1status.motorDirection = 0x02;
Count is a hex number because it is BCD (Binary coded decimal) http://en.wikipedia.org/wiki/Binary-coded_decimal
In BCD, you use 4 bits to represent the numbers 0-9, there are some unused bit patterns, so the easy way to work with it is to just use hex (which also uses 4 bits to represent the numbers 0x0-0xf), but in BCD you just don't use the numbers 0xa-0xf.
The reason motorDirection is 0x02 is because he wants motor direction of 10, but it is a 2 bit field, so I am assuming that he means 10 binary, which is 0x02 hex.
Consider meeting these requirements in the order they are specified. Note that some requirements are merged together as one. This is often the case for assignments; Lecturers aren't always perfect linguists or logicians, particularly IT lecturers.
1: Create a structure that will hold bits the represent the following:
count: a 4 bit BCD number
red LED: 1 bit
green LED: 1 bit
motor direction: 2 bits
Name the structure motorStatus
Respond to this, first, without using typedef. Use the type int for bitfields. Next requirement:
Use typedef to name this new data type: mtrStatus_t
You've demonstrated the ability to write basic typedefs. typedef unsigned char mtrStatus_t; means "I define mtrStatus_t to alias unsigned char". Now, write a basic typedef like this that means "I define mtrStatus_t to alias struct motorStatus". Put it after the struct motorStatus definition, so that the compiler can see what it's aliasing.
2: Create a new instance of the structure and name it motor1Status
To clarify, your lecturer is asking you to declare a variable named motor1Status, which has the type mtrStatus_t or struct motorStatus. I presume you can declare variables, but correct me if I'm wrong.
3: Write statements to initialize the new structure members as follows:
count: 9 BCD
red LED: 1
green LED: 0
Motor Direction: 10
count: 0x09; redLED: 0x01; greenLED: 0x00 motorDirection: 0x0A
Your lecturer is asking for initialisation, not assignment. In char str[] = "fubar"; and char str[] = {'h','e','l','l','o','\0'};, str is declared and initialised to store a string corresponding to "fubar". In char str[6]; strcpy(str, "fubar"); str is declared without an initialisation, and each byte in "fubar" is copied (assigned) to the corresponding positions in str. How do you initialise a struct? Very similarly to the second str initialisation.
struct length_prefixed_string {
size_t length;
int zero;
char string[];
};
/* Initialisation here: */
struct length_prefixed_string hello = { .length = 5,
.string = "hello" };
This example uses a flexible array member, which can only be declared at the end of a struct: char string[];. It conveys an array of unknown length located at the end of the struct, which isn't counted towards sizeof (struct length_prefix_string). For this reason, the example stores the unknown length in the length argument. This is a little off-topic, but you can see an initialisation (as opposed to an assignment) above. This example differentiates initialisation from assignment; You can't assign the .string member of this struct with hello.string = "hello";.
Another difference is: Any members not mentioned by the initialisation will be assigned a zero value (but only when an initialisation is present), hence the value of hello.zero in the above example will be 0. For this reason, you can declare an array and zero-fill it with one statement: int array[size] = { 0 }; (another difference between assignment and initialisation: int array[size]; array = { 0 }; is invalid). Having said that, it'd be a good idea to ignore this fact for the purpose of your task, and explicitly initialise greenLED so that your marking examiner can't misunderstand.
I do hope I was helpful, here...
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Practical Use of Zero-Length Bitfields
Why some structures have zero-width bit fields, and why is it required?
struct foo {
int a:3;
int b:2;
int :0; // Force alignment to next boundary.
int c:4;
int d:3;
};
int main()
{
int i = 0xFFFF;
struct foo *f = (struct foo *)&i;
printf("a=%d\nb=%d\nc=%d\nd=%d\n", f->a, f->b, f->c, f->d);
return 0;
}
The output of above program is
manav#os-team:~/programs/test$ ./a.out
a=-1
b=-1
c=-8
d=0
Please explain why these values are negative, and the memory layout of these variables inside the structure?
From this first hit on a Google search:
Bit fields with a length of 0 must be unnamed. Unnamed bit fields cannot be referenced or initialized. A zero-width bit field can cause the next field to be aligned on the next container boundary where the container is the same size as the underlying type of the bit field.
As for the second part of your question, you set some of the bitfields in your struct to all 1s, and since these fields are signed then this results in a negative value for these fields. You can see this more effectively if you set the entire struct to 1s and look at the values in both signed and unsigned representations, e.g.
int main()
{
struct foo f;
memset(&f, 0xff, sizeof(f));
printf("a=%d\nb=%d\nc=%d\nd=%d\n", f.a, f.b, f.c, f.d); // print fields as signed
printf("a=%u\nb=%u\nc=%u\nd=%u\n", f.a, f.b, f.c, f.d); // print fields as unsigned
return 0;
}
The memory layout is "it depends" and you can't count on any particular layout from any particular compiler. In fact, you may see different layout from any given compiler by changing its settings. Don't try to guess, intuit, or depend on the layout.
Negatives - all your elements are ints which are signed, so they are negative since you've initialized every bit to 1, so you've got sign bits set. As for d - beats me. Typo?
As stated here, zero-length bitfields add alignment between bitfields. If we have several bitfields in a row, their layout is compact, but if we want to align one of them to byte/word/dword boundary, we need to put a zero-length bitfield between this and the previous one.
Example from the link above:
struct on_off {
unsigned light : 1;
unsigned toaster : 1;
int count; /* 4 bytes */
unsigned ac : 4; // this and
unsigned : 4; // this and
unsigned clock : 1; // this bitfields are next to each other
unsigned : 0;
unsigned flag : 1; // this bitfield is at a 4 bytes boundary.
} kitchen ;
Numbers are negative because the bitfields are signed, i.e. if you have a signed char variable, its size is 8 bits which can hold 256 different values. Half of the values are positive, the rest are negative and 0. The most significant bit indicates sign (1 for negative, 0 for positive). Regarding zero-length bitfields see here: Practical Use of Zero-Length Bitfields