Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Bitfields - the answer?

122 views
Skip to first unread message

Erik Cato

unread,
Jun 5, 2002, 5:18:43 PM6/5/02
to
Hi group!

/* snip */
typedef unsigned short u16;

struct
{
u16 bit1 : 1;
u16 bit2 : 1;
u16 bit3 : 1;
u16 bit4 : 1;
u16 bit5 : 1;
u16 bit6 : 1;
u16 bit7 : 1;
u16 bit8 : 1;
u16 bit9 : 1;
u16 bit10 : 1;
u16 bit11 : 1;
u16 bit12 : 1;
u16 bit13 : 1;
u16 bit14 : 1;
u16 bit15 : 1;
u16 bit16 : 1;
u16 bit17 : 1;
} g_Flags;

/* snip */

According to my interpretation of the paragraph below the struct
in the snip above shouldnt have greater size then 4 bytes? Anyone disagree?
Agree? Im sorry to bother you a third time with this but it seems hard to
get a clear answer. I still feel a little unsecure about reading the standard.

ISO/IEC 9899:1999 (E)

6.7.2.1 Structure and union specifiers

10 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.

//Erik Cato

Ben Pfaff

unread,
Jun 5, 2002, 5:24:35 PM6/5/02
to
erik...@japro.se (Erik Cato) writes:

> /* snip */
> typedef unsigned short u16;
>
> struct
> {
> u16 bit1 : 1;

Problem: bit-fields may not portably have type "unsigned short",
see C99 6.7.2.1#3.

> u16 bit2 : 1;
> u16 bit3 : 1;
> u16 bit4 : 1;
> u16 bit5 : 1;
> u16 bit6 : 1;
> u16 bit7 : 1;
> u16 bit8 : 1;
> u16 bit9 : 1;
> u16 bit10 : 1;
> u16 bit11 : 1;
> u16 bit12 : 1;
> u16 bit13 : 1;
> u16 bit14 : 1;
> u16 bit15 : 1;
> u16 bit16 : 1;
> u16 bit17 : 1;
> } g_Flags;
>
> /* snip */
>
> According to my interpretation of the paragraph below the struct
> in the snip above shouldnt have greater size then 4 bytes? Anyone disagree?
> Agree? Im sorry to bother you a third time with this but it seems hard to
> get a clear answer. I still feel a little unsecure about reading the standard.

The smallest addressable storage unit the implementation could
allocate is a byte, which is at least 8 bits in size. So the 17
1-bit units above won't take up more than 3 byte-sized storage
units, but it could allocate, say, one 64-bit storage unit or one
128-bit storage unit. It can also add any amount of padding
after the bit-field storage unit(s).
--
"To get the best out of this book, I strongly recommend that you read it."
--Richard Heathfield

Dann Corbit

unread,
Jun 5, 2002, 5:32:30 PM6/5/02
to
"Erik Cato" <erik...@japro.se> wrote in message
news:92382512.02060...@posting.google.com...


A 128 bit integer is an addressable storage unit. Suppose that an
implementation has 128 bit size_t and the implementer decides to implement
bit fields using a size_t.

I don't think your 'short' modifier does anything, by the way. In other
words, I see no difference between:

{
unsigned b:1;
}
and
{
unsigned short b:1;
}
or
{
unsigned long long b:1;
}

After all, we are talking about a single {unsigned} bit in each and every
case. So I guess I disagree with you.
--
C-FAQ: http://www.eskimo.com/~scs/C-faq/top.html
"The C-FAQ Book" ISBN 0-201-84519-9
C.A.P. FAQ: ftp://cap.connx.com/pub/Chess%20Analysis%20Project%20FAQ.htm


pete

unread,
Jun 5, 2002, 6:05:22 PM6/5/02
to
Erik Cato wrote:
>
> Hi group!
>
> /* snip */
> typedef unsigned short u16;
>
> struct
> {
> u16 bit1 : 1;
> u16 bit2 : 1;
> u16 bit3 : 1;
> u16 bit4 : 1;
> u16 bit5 : 1;
> u16 bit6 : 1;
> u16 bit7 : 1;
> u16 bit8 : 1;
> u16 bit9 : 1;
> u16 bit10 : 1;
> u16 bit11 : 1;
> u16 bit12 : 1;
> u16 bit13 : 1;
> u16 bit14 : 1;
> u16 bit15 : 1;
> u16 bit16 : 1;
> u16 bit17 : 1;
> } g_Flags;
>
> /* snip */

The bitfields are supposed to be either int or unsigned int.
I don't know if using the keyword "short" invokes undefined behavior
here, but I do know that it doesn't help at all.

> According to my interpretation of the paragraph below the struct
> in the snip above shouldnt have greater size then 4 bytes?
> Anyone disagree?
> Agree?

It would probably be 4 on systems where CHAR_BIT is 8
and sizeof(int) is either 2 or 4, but no guarantees.

> Im sorry to bother you a third time with this but it seems hard to
> get a clear answer. I still feel a little unsecure about reading
>the standard.
>
> ISO/IEC 9899:1999 (E)
>
> 6.7.2.1 Structure and union specifiers
>
> 10 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.
>
> //Erik Cato

--
pete

Jack Klein

unread,
Jun 6, 2002, 8:30:59 PM6/6/02
to
On Wed, 5 Jun 2002 14:32:30 -0700, "Dann Corbit" <dco...@connx.com>
wrote in comp.lang.c:

[snip]

> I don't think your 'short' modifier does anything, by the way. In other
> words, I see no difference between:
>
> {
> unsigned b:1;
> }
> and
> {
> unsigned short b:1;
> }
> or
> {
> unsigned long long b:1;
> }
>
> After all, we are talking about a single {unsigned} bit in each and every
> case. So I guess I disagree with you.

I do see a difference between the three snippets. The first is well
defined, the other two undefined.

--
Jack Klein
Home: http://JK-Technology.Com
FAQs for
comp.lang.c http://www.eskimo.com/~scs/C-faq/top.html
comp.lang.c++ http://www.parashift.com/c++-faq-lite/
alt.comp.lang.learn.c-c++ ftp://snurse-l.org/pub/acllc-c++/faq

Dan Pop

unread,
Jun 7, 2002, 8:41:16 AM6/7/02
to

Or _Bool in C99.

>I don't know if using the keyword "short" invokes undefined behavior
>here, but I do know that it doesn't help at all.

It's a "shall" outside a syntax rule or a constraint, so it is undefined
behaviour, indeed. Which means that, a compiler supporting unsigned
short bit fields as an extension need not emit a diagnostic.

>> According to my interpretation of the paragraph below the struct
>> in the snip above shouldnt have greater size then 4 bytes?
>> Anyone disagree?
>> Agree?
>
>It would probably be 4 on systems where CHAR_BIT is 8
>and sizeof(int) is either 2 or 4, but no guarantees.

sizeof(int) is irrelevant here, only the value of CHAR_BIT is relevant,
because it allows us to compute the minimum size the structure can have.
There is nothing preventing such a structure from having a size of 3 on
an implementation with 2 or 4-byte int's. And this is what I would
expect from a compiler designed to generate code for 8-bit hardware.

>> Im sorry to bother you a third time with this but it seems hard to
>> get a clear answer. I still feel a little unsecure about reading
>>the standard.
>>
>> ISO/IEC 9899:1999 (E)
>>
>> 6.7.2.1 Structure and union specifiers
>>
>> 10 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.

This shows you how to compute the minimum size of the structure, taking
into account the value of CHAR_BIT. The maximum size is unspecified,
because the implementation is free to insert as much padding as it wants,
even if the bit-fields are guaranteed to be tightly packed.

Dan
--
Dan Pop
DESY Zeuthen, RZ group
Email: Dan...@ifh.de

Ben Pfaff

unread,
Jun 7, 2002, 12:27:23 PM6/7/02
to
pete <pfi...@mindspring.com> writes:

> Erik Cato wrote:
> >
> > Hi group!
> >
> > /* snip */
> > typedef unsigned short u16;
> >
> > struct
> > {

[...]


> > u16 bit17 : 1;
> > } g_Flags;
> >
> > /* snip */
>
> The bitfields are supposed to be either int or unsigned int.

`int' is a poor choice for 1-bit bit-fields, since it can
designate either a signed or unsigned int and thus the only value
it is required to hold is 0.

See C99 6.7.2#5:

Each of the comma-separated sets designates the same type,
except that for bit-fields, it is implementation-defined
whether the specifier int designates the same type as signed
int or the same type as unsigned int.

--
"In My Egotistical Opinion, most people's C programs should be indented six
feet downward and covered with dirt." -- Blair P. Houghton

Erik Cato

unread,
Jun 8, 2002, 9:27:06 AM6/8/02
to
Dan...@ifh.de (Dan Pop) wrote in message news:<adq9lc$rkk$1...@sunnews.cern.ch>...

In my opinion bitfields seems pretty much useless. I can see only two
reasons for using them and both are impossible (in a portable way )
according to the standard.

1. For accessing bits or groups of bits in a hardware port.
Impossibles due
to "... The order of allocation of bit-fields within a unit
(high-order to
low-order or low-order to high-order) is implementation-defined ...
"

2. For packing bit-flags. Impossible due to "... An implementation may


allocate any addressable storage unit large enough to hold a
bit-field".

Why packing bits if the implementation may allocate a gazillion
bytes to
store them.

Am i still missing something or?

Is masking the only portable way of doing memory efficient bit-flags?

The reason for all my question is that i want a nice clean portable
way
of doing bit-flags. But i need to be sure the implementation dont
allocate
a huge amount of memory for every "flagbank".

//Erik Cato

Kevin Bracey

unread,
Jun 9, 2002, 10:48:07 AM6/9/02
to
In message <92382512.02060...@posting.google.com>
erik...@japro.se (Erik Cato) wrote:

> In my opinion bitfields seems pretty much useless. I can see only two
> reasons for using them and both are impossible (in a portable way )
> according to the standard.
>
> 1. For accessing bits or groups of bits in a hardware port.
> Impossibles due
> to "... The order of allocation of bit-fields within a unit
> (high-order to
> low-order or low-order to high-order) is implementation-defined ...
> "

Well, no, each implementation is required to document the allocation order,
so you will always know for your particular compiler how it is done. This
doesn't add many extra portability problems beyond those due to accessing a
hardware port.

> 2. For packing bit-flags. Impossible due to "... An implementation may
> allocate any addressable storage unit large enough to hold a
> bit-field".
> Why packing bits if the implementation may allocate a gazillion
> bytes to
> store them.

Well, it's a statement of intent. An implementation may conversely put a
gazillion padding bytes in each structure, making a structure of two ints
much larger than two ints, but one doesn't avoid structures because of that.

A series of bitfield members can be smaller than a series of standard normal
members, and is unlikely to be larger on any reasonable implementation.

--
Kevin Bracey
http://www.bracey-griffith.freeserve.co.uk/

0 new messages