Velocity Reviews > bitfield in struct and padding

# bitfield in struct and padding

Stanley Rice
Guest
Posts: n/a

 11-10-2011
Dear all

Here I declare a structure as follows:

struct flag
{
unsigned int a : 8; /* 1 - 7 is yield the same result*/
char b;
char c;
char d;
};

and sizeof(struct flag) equals 4, which is intuitive.

But when I make a little modification, where the bitwidth allocated to
a is 9:

struct flag
{
unsigned int a : 9; /* modification here */
char b;
char c;
char d;
};

and sizeof(struct flag) equals 8, but not 5, where variable 2 bytes
are allocated to variable a, and 3 bytes are allocated to the
following char type variable.

I want to know how many bytes are allocated to variable a? and how the
padding in the obove structure performs.

tom st denis
Guest
Posts: n/a

 11-10-2011
On Nov 10, 9:29*am, Stanley Rice <(E-Mail Removed)> wrote:
> Dear all
>
> Here I declare a structure as follows:
>
> struct flag
> {
> * * unsigned int * *a : 8; /* 1 - 7 is yield the same result*/
> * * char * * * * * *b;
> * * char * * * * * *c;
> * * char * * * * * *d;
>
> };
>
> and sizeof(struct flag) equals 4, which is intuitive.
>
> But when I make a little modification, where the bitwidth allocated to
> a is 9:
>
> struct flag
> {
> * * unsigned int * *a : 9; /* modification here */
> * * char * * * * * *b;
> * * char * * * * * *c;
> * * char * * * * * *d;
>
> };
>
> and sizeof(struct flag) equals 8, but not 5, where variable 2 bytes
> are allocated to variable a, and 3 bytes are allocated to the
> following char type variable.
>
> I want to know how many bytes are allocated to variable a? and how the
> padding in the obove structure performs.

That's more of a compiler question than anything. Chances are good
you're on a 32 or 64-bit host where it is optimizing the structure by
whole.

There are usually [per-compiler] pragmas to be had to pack structure
densely. They're not portable.

From experience, if you are using bit-fields it's probably because

a) You're writing non-portable code that talks to hardware

or

b) You're trying to avoid having to use & operators explicitly in your
code when dealing with truncated values...

Personally I've never used bitfields in anything I've written in the
19 years I've been using C [both as an amateur and a pro]...

Tom

Ben Bacarisse
Guest
Posts: n/a

 11-10-2011
Stanley Rice <(E-Mail Removed)> writes:

> Here I declare a structure as follows:
>
> struct flag
> {
> unsigned int a : 8; /* 1 - 7 is yield the same result*/
> char b;
> char c;
> char d;
> };
>
> and sizeof(struct flag) equals 4, which is intuitive.
>
> But when I make a little modification, where the bitwidth allocated to
> a is 9:
>
> struct flag
> {
> unsigned int a : 9; /* modification here */
> char b;
> char c;
> char d;
> };
>
> and sizeof(struct flag) equals 8, but not 5, where variable 2 bytes
> are allocated to variable a, and 3 bytes are allocated to the
> following char type variable.
>
> I want to know how many bytes are allocated to variable a? and how the
> padding in the obove structure performs.

I don't think there is a simple way to find out. It must be more than 1
on machine with CHAR_BIT==8, but other than that all you can tell is
where 'b' is. If, say, offsetof(struct flag, b) == 4, you can't tell if
this is due to padding or the size of the unit used to hold 'a', but
does it matter?

More to the point, what is the reason you need to know? What are you
trying to achieve? If your objective is to control the layout, your
compiler may provide non-standard ways to do that. But even so, I'd
want to know the ultimate objective, because there may be better ways to
achieve it.

--
Ben.

Malcolm McLean
Guest
Posts: n/a

 11-10-2011
On Nov 10, 4:29*pm, Stanley Rice <(E-Mail Removed)> wrote:
> Dear all
>
> Here I declare a structure as follows:
>
> struct flag
> {
> * * unsigned int * *a : 8; /* 1 - 7 is yield the same result*/
> * * char * * * * * *b;
> * * char * * * * * *c;
> * * char * * * * * *d;
>
> };
>
> and sizeof(struct flag) equals 4, which is intuitive.
>
> But when I make a little modification, where the bitwidth allocated to
> a is 9:
>
> struct flag
> {
> * * unsigned int * *a : 9; /* modification here */
> * * char * * * * * *b;
> * * char * * * * * *c;
> * * char * * * * * *d;
>
> };
>
> and sizeof(struct flag) equals 8, but not 5, where variable 2 bytes
> are allocated to variable a, and 3 bytes are allocated to the
> following char type variable.
>
> I want to know how many bytes are allocated to variable a? and how the
> padding in the obove structure performs.
>

You can easily find out.

struct flag s;
printf("%d %d %d %d\n", (int) (&s.b - &s), (int)(&s.c - &s), (int)
(&s.d - &s), (int) sizeof(s));

That will tell you where the padding has been inserted. Clearly on any
system with 8 bit bytes you will need some padding, since 9 bits can't
fit into a whole number of bytes.

James Dow Allen
Guest
Posts: n/a

 11-10-2011
On Nov 10, 9:40*pm, tom st denis <(E-Mail Removed)> wrote:
> From experience, if you are using bit-fields it's probably because
>
> a) You're writing non-portable code that talks to hardware, or

> b) You're trying to avoid having to use & operators explicitly in your
> code when dealing with truncated values..., [or]

c) taking advantage, in routine(s) you want optimized for
speed, of some compilers which deliver better opcodes when
bitfield is used (True of the Sun 68k 1988 compiler;
Perhaps present-day compilers are so good,
this is no longer a problem), or

d) for better readability, e.g. to write
q->bptr = dval; /* Stmt D1 */
| dval << FOOSHIF; /* Stmt D2 */

> Personally I've never used bitfields in anything I've written in the
> 19 years I've been using C [both as an amateur and a pro]...
>
> Tom

I can say the same, more-or-less. It is the concern about
portability ease that often leads the coder to avoid them unless
there is a very important benefit.

Looking at my example (d) above, I consider that the first form
has a significant readability win. What do others think?

James Dow Allen

tom st denis
Guest
Posts: n/a

 11-10-2011
On Nov 10, 1:53*pm, James Dow Allen <(E-Mail Removed)> wrote:
> On Nov 10, 9:40*pm, tom st denis <(E-Mail Removed)> wrote:
>
> > From experience, if you are using bit-fields it's probably because

>
> > a) You're writing non-portable code that talks to hardware, or
> > b) You're trying to avoid having to use & operators explicitly in your
> > code when dealing with truncated values..., [or]

>
> c) taking advantage, in routine(s) you want optimized for
> speed, of some compilers which deliver better opcodes when
> bitfield is used (True of the Sun 68k 1988 compiler;
> Perhaps present-day compilers are so good,
> this is no longer a problem), or
>
> d) for better readability, e.g. to write
> * * q->bptr = dval; */* Stmt D1 */
> * * * * * * | dval << FOOSHIF; /* Stmt D2 */
>
> > Personally I've never used bitfields in anything I've written in the
> > 19 years I've been using C [both as an amateur and a pro]...

>
> > Tom

>
> I can say the same, more-or-less. *It is the concern about
> portability ease that often leads the coder to avoid them unless
> there is a very important benefit.
>
> Looking at my example (d) above, I consider that the first form
> has a significant readability win. *What do others think?

I'd use a macro....

q->d = SET_D_FIELD(potato);

or something to that effect (I write HW drivers a large part of my day
lately...).

Tom

Keith Thompson
Guest
Posts: n/a

 11-10-2011
Malcolm McLean <(E-Mail Removed)> writes:
> On Nov 10, 4:29Â*pm, Stanley Rice <(E-Mail Removed)> wrote:
>> Here I declare a structure as follows:
>>
>> struct flag
>> {
>> Â* Â* unsigned int Â* Â*a : 8; /* 1 - 7 is yield the same result*/
>> Â* Â* char Â* Â* Â* Â* Â* Â*b;
>> Â* Â* char Â* Â* Â* Â* Â* Â*c;
>> Â* Â* char Â* Â* Â* Â* Â* Â*d;
>>
>> };
>>
>> and sizeof(struct flag) equals 4, which is intuitive.
>>
>> But when I make a little modification, where the bitwidth allocated to
>> a is 9:
>>
>> struct flag
>> {
>> Â* Â* unsigned int Â* Â*a : 9; /* modification here */
>> Â* Â* char Â* Â* Â* Â* Â* Â*b;
>> Â* Â* char Â* Â* Â* Â* Â* Â*c;
>> Â* Â* char Â* Â* Â* Â* Â* Â*d;
>>
>> };
>>
>> and sizeof(struct flag) equals 8, but not 5, where variable 2 bytes
>> are allocated to variable a, and 3 bytes are allocated to the
>> following char type variable.
>>
>> I want to know how many bytes are allocated to variable a? and how the
>> padding in the obove structure performs.
>>

> You can easily find out.
>
> struct flag s;
> printf("%d %d %d %d\n", (int) (&s.b - &s), (int)(&s.c - &s), (int)
> (&s.d - &s), (int) sizeof(s));

I don't believe that will compile. &s.b is of type char*; &s is of type
struct flag*.

Just use the offsetof() macro, defined in <stddef.h>.

Here's a program I just threw together (note that offsetof() can't be
applied to a bit-field).

#include <stdio.h>
#include <stddef.h>

struct flag7
{
unsigned int a : 7;
char b;
char c;
char d;
};

struct flag8
{
unsigned int a : 8;
char b;
char c;
char d;
};

struct flag9
{
unsigned int a : 9;
char b;
char c;
char d;
};

int main(void) {
printf("sizeof (struct flag7) = %d\n", (int)sizeof (struct flag7));
printf(" b at %d\n", (int)offsetof(struct flag7, b));
printf(" c at %d\n", (int)offsetof(struct flag7, c));
printf(" c at %d\n", (int)offsetof(struct flag7, d));

printf("sizeof (struct flag = %d\n", (int)sizeof (struct flag);
printf(" b at %d\n", (int)offsetof(struct flag8, b));
printf(" c at %d\n", (int)offsetof(struct flag8, c));
printf(" c at %d\n", (int)offsetof(struct flag8, d));

printf("sizeof (struct flag9) = %d\n", (int)sizeof (struct flag9));
printf(" b at %d\n", (int)offsetof(struct flag9, b));
printf(" c at %d\n", (int)offsetof(struct flag9, c));
printf(" c at %d\n", (int)offsetof(struct flag9, d));

return 0;
}

On my system, the output is:

sizeof (struct flag7) = 4
b at 1
c at 2
c at 3
sizeof (struct flag = 4
b at 1
c at 2
c at 3
sizeof (struct flag9) = 8
b at 2
c at 3
c at 4

--
Keith Thompson (The_Other_Keith) http://www.velocityreviews.com/forums/(E-Mail Removed) <http://www.ghoti.net/~kst>
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"