Bit filed usage

C

Capstar

Hi NG,

I have a question about the usage of bitfileds in a structure.
for instance:

struct pcard
{
unsigned pips : 4;
unsigned suit : 2;
};

The only reason I see fot using this is to save memory. But isn't it true
that on most systems memory isn't that much of an issue to pack data like
this? And even on some embedded machine whitout much memory, I'm not sure
the memory gain by packing your structures will be much bigger than the loss
you get from the increased code size. Maybe when you have lots of these
structures you will gain something.

Another reason I would consider this helpfull would be if the structures
would be written to some binary file. In my opinion file size does matter.
The only problem I see in this case is that every machine, and even a
different compiler at the same machine, could map the bits somewhere else in
a word. This would mean that the file is incompatible with anything but the
same compiler and the same machine.

So I am very curious if anybody ever uses these kind of structures and where
they are used for.

Mark
 
S

Simon Wilkins

Capstar said:
Hi NG,

I have a question about the usage of bitfileds in a structure.
for instance:

struct pcard
{
unsigned pips : 4;
unsigned suit : 2;
};

The only reason I see fot using this is to save memory. But isn't it true
that on most systems memory isn't that much of an issue to pack data like
this? And even on some embedded machine whitout much memory, I'm not sure
the memory gain by packing your structures will be much bigger than the loss
you get from the increased code size. Maybe when you have lots of these
structures you will gain something.

Another reason I would consider this helpfull would be if the structures
would be written to some binary file. In my opinion file size does matter.
The only problem I see in this case is that every machine, and even a
different compiler at the same machine, could map the bits somewhere else in
a word. This would mean that the file is incompatible with anything but the
same compiler and the same machine.

So I am very curious if anybody ever uses these kind of structures and where
they are used for.

Mark

I suspect this is off-topic, but we use bit-field structures when
mapping data for RFID tags where the memory is usually measured in bits,
not bytes let alone kB.
 
P

Pieter Droogendijk

struct pcard
{
unsigned pips : 4;
unsigned suit : 2;
};

The only reason I see fot using this is to save memory. But isn't it true
that on most systems memory isn't that much of an issue to pack data like
this? And even on some embedded machine whitout much memory, I'm not sure
the memory gain by packing your structures will be much bigger than the loss
you get from the increased code size. Maybe when you have lots of these
structures you will gain something.

A reason for using these is to get around those annoying bitwise operations.
They can be a real pain, and even when macro-ifying the operations, they don't
improve readability.
Bitfields leave those operations to the compiler.

And the memory conservation is not an issue, since the structs are aligned
anyway. The example you gave won't take up just 6 bits, it'll align and take up
a byte, or a word, or an int, depending on your platform.

Just using a struct of char's uses only slightly more memory, but gets rid of
all the operations. All depends on what you want, more memory or more cycles.
 
C

Capstar

Pieter Droogendijk said:
A reason for using these is to get around those annoying bitwise operations.
They can be a real pain, and even when macro-ifying the operations, they don't
improve readability.
Bitfields leave those operations to the compiler.

Yes I understand, but what do you need those bitwise operations for if you
don't use bits anyway? I mean bits in the sence that you don't measure how
many bits you need for something and then stuff as many as possible in one
word, but just use a word or more for every variable. That would also get
you around those bitwise operations.
And the memory conservation is not an issue, since the structs are aligned
anyway. The example you gave won't take up just 6 bits, it'll align and take up
a byte, or a word, or an int, depending on your platform.

Just using a struct of char's uses only slightly more memory, but gets rid of
all the operations. All depends on what you want, more memory or more cycles.

--
char*x(c,k,s)char*k,*s;{if(!k)return*s-36?x(0,0,s+1):s;if(s)if(*s)c=10+(c?(x
(
c,k,0),x(c,k+=*s-c,s+1),*k):(x(*s,k,s+1),0));else
c=10;printf(&x(~0,0,k)[c-~-
c+"1"[~c<-c]],c);}main(){x(0,"^[kXc6]dn_eaoh$%c","-34*1'.+(,03#;+,)/'///*");
}
 
C

Capstar

Zoran Cutura said:
Your understanding of what the most systems are is, IMHO, wrong. Have
you ever noticed that there are so many embedded devices out there
having only a few kBytes of RAM available? For example in automotive
typical so called ECU's (electronic control units) run with controllers
having between 120 and 500 kBytes of ROM where the program code can be
stored in, but only with 2 to 16 kBytes of RAM that can be used for
data. That usually brings in the need to care about Bits and Bytes.

I must admit that there are a lot of embedded systems around nowadays, but I
didn't realise that the ROM is often that much bigger than the RAM. I
actually assumed the other way around. Which is probably a bit naive since
ROM is much cheaper than RAM.
So this actually is a good answer on my question why to use bitfield
operators.
You're probably thinking about most programmers being programmig for systems
where memory isn't a issue, but that is a claim that is hard to prove.

Anyway, when you start a project or program, you usually do not need to
care about memory usage and speed form the very start. It should be
sufficient to make the program functionally correct and care about size
and speed when you recognize that there are problems with these.

As you may have recognized yourself, structures shouldn't be written to
binary files as they are. Structures are very implementation specific
and as you say even two versions of a compiler may constitute 'em in
different ways. That is an issue with all structs not only bit fields.

I understand. I didn't mean writing structs to a binary file, but for
instance creating a one word header in a file. If that file contains some
flags, you could use masks and bit operations to set and clear flags, or use
a bitfield structure, and use that. Well actually the last is not possible,
but that was what I tried to say in my OP.

Mark
 
A

Arthur J. O'Dwyer

Yes I understand, but what do you need those bitwise operations for if you
don't use bits anyway? I mean bits in the sence that you don't measure how
many bits you need for something and then stuff as many as possible in one
word, but just use a word or more for every variable. That would also get
you around those bitwise operations.

There are some applications for bitwise operators;
encryption and compression come to mind. IIRC,
some schemes for data encryption require bitwise
XORs and shifts on 24-bit data, which could be a
little annoying on platforms with 16- and 32-bit
words. So if one really wanted to be pedantic,
one could write

struct int24_s
{
unsigned value: 24;
};

typedef struct int24_s int24_s;

#define VALUE(int24) ((int24).value)

and then use the regular bitwise operators on
the VALUEs of int24_s objects, without worrying
about bit masks.

The caveat here is that I'm not sure whether
the above bit-field definition is guaranteed to
work on platforms where 'unsigned int' has fewer
than 24 value bits. Expert advice welcome.

-Arthur
 
J

John Devereux

Zoran Cutura said:
Your understanding of what the most systems are is, IMHO, wrong. Have
you ever noticed that there are so many embedded devices out there
having only a few kBytes of RAM available? For example in automotive
typical so called ECU's (electronic control units) run with controllers
having between 120 and 500 kBytes of ROM where the program code can be
stored in, but only with 2 to 16 kBytes of RAM that can be used for
data. That usually brings in the need to care about Bits and Bytes.

In fact, I suspect that when C bitfields were "invented", the machines of the
time would have been equivalent in resources to the embedded systems of which you
speak.

Are there any legitimate uses other than saving space in structures? I
have seen them used for defining peripheral hardware register layouts, but that
is very bad form here so I won't even mention it :)
 
J

Jack Klein

Hi NG,

I have a question about the usage of bitfileds in a structure.
for instance:

struct pcard
{
unsigned pips : 4;
unsigned suit : 2;
};

The only reason I see fot using this is to save memory. But isn't it true
that on most systems memory isn't that much of an issue to pack data like
this? And even on some embedded machine whitout much memory, I'm not sure
the memory gain by packing your structures will be much bigger than the loss
you get from the increased code size. Maybe when you have lots of these
structures you will gain something.

Have you ever worked on an embedded system without much memory? If
you haven't had the experience, your experience is pretty useless.
Try writing C code to run in an environment with 4K (4K octets or
bytes, not kilobytes or megabytes) read-only code space and less than
128 8-bit bytes of read/write RAM.

Then you'll be qualified to have an _informed_ opinion about writing C
code for such environments.
Another reason I would consider this helpfull would be if the structures
would be written to some binary file. In my opinion file size does matter.
The only problem I see in this case is that every machine, and even a
different compiler at the same machine, could map the bits somewhere else in
a word. This would mean that the file is incompatible with anything but the
same compiler and the same machine.

So I am very curious if anybody ever uses these kind of structures and where
they are used for.

Mark

If you don't see the usefulness of bit-fields in the code your write
for the execution environments your code runs in, by all means feel
free not to use them.

Nobody ever said you had to use them, or even suggested that you use
them.

--
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
 
J

Jack Klein

Your understanding of what the most systems are is, IMHO, wrong. Have
you ever noticed that there are so many embedded devices out there
having only a few kBytes of RAM available? For example in automotive

"kBytes"? That's among the larger size for embedded systems. I've
done quite a few applications in my time with C for 8051 derivative's
with 128 bytes, some of which has to be left for CPU registers.
typical so called ECU's (electronic control units) run with controllers
having between 120 and 500 kBytes of ROM where the program code can be
stored in, but only with 2 to 16 kBytes of RAM that can be used for
data. That usually brings in the need to care about Bits and Bytes.

You're probably thinking about most programmers being programmig for systems
where memory isn't a issue, but that is a claim that is hard to prove.

Anyway, when you start a project or program, you usually do not need to
care about memory usage and speed form the very start. It should be
sufficient to make the program functionally correct and care about size
and speed when you recognize that there are problems with these.

As you may have recognized yourself, structures shouldn't be written to
binary files as they are. Structures are very implementation specific
and as you say even two versions of a compiler may constitute 'em in
different ways. That is an issue with all structs not only bit fields.

--
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
 
D

Don Starr

Try writing C code to run in an environment with 4K (4K octets or
bytes, not kilobytes or megabytes) read-only code space and less than
128 8-bit bytes of read/write RAM.

Now I feel spoiled with my 8k-word ROM, 384-byte RAM PIC ;)

(And, yes, I use bitfields extensively. I even use them to <gasp!> control bits in hardware
registers.)

-Don
 
Z

Zoran Cutura

Jack Klein said:
On 8 Aug 2003 11:45:26 GMT, Zoran Cutura
....

"kBytes"? That's among the larger size for embedded systems. I've
done quite a few applications in my time with C for 8051 derivative's
with 128 bytes, some of which has to be left for CPU registers.

I've not, still I know that there are such systemsi, and I'm about to
experience such systems in the near future.

I probably should have mentioned the even smaller systems, but I have or
had the feeling that the number of such systems is rather low, when one
comes to think about this in more depth, one recognizes that feelings
are not always to be trusted. ;-)
 
D

Dan Pop

In said:
In fact, I suspect that when C bitfields were "invented", the machines of the
time would have been equivalent in resources to the embedded systems of which you
speak.

Not really. Even the first PDP-11 machine used by Ritchie was capable
of addressing 56K of RAM (the upper 8K were reserved for I/O registers).

By the time C started to have the shape described in K&R1, the PDP-11/45
was the "standard" Unix hardware (a single program could easily access
64k of code and 64k of data).
Are there any legitimate uses other than saving space in structures? I
have seen them used for defining peripheral hardware register layouts, but that
is very bad form here so I won't even mention it :)

I strongly suspect that Ritchie added them to the language so that he
could write readable device drivers. Such code is a pain to read if
bit fields are not used. To the generated object code, it makes little
difference if the shifting and masking is coming from the source code or
is inlined by the compiler, as a result of processing bit fields: given
the way information is mapped on certain hardware registers, it is
unavoidable.

I have yet to see a "high level" programming task requiring or benefitting
from the usage of bit fields.

Dan
 
J

John Devereux

You shouldn't confuse this newsgroup and the real world.

No, I don't think it's just the newsgroup :) I've seen this advice
elsewhere, long before I discovered clc!
OTOH, it is true that, if you need to write a "portable" device driver
(i.e. one that works on any hardware platform supported by something like
xBSD or Linux), bit fields are usually not an option.

I think the portability issue is more to do with portability between
compilers, rather than hardware platforms. Can standard C guarantee
bit alignment? (I didn't think it could).

For example, consider the use of bitfields to define a register layout
in a microcontroller. There is no need for the bitfields to be
portable to another type of microcontroller since the hardware they
specify will be totally different anyway. But it would be nice if you
could use any standard C compiler without all the bit positions moving
around each time you change compilers.
 
J

John Devereux

The compiler's behaviour is often dictated by the underlying hardware.
gcc allocates bit fields differently on little endian vs big endian
platforms. OTOH, different compilers generating code for the same
hardware platform usually align bit fields in the same way.


It could, if it wanted to, but it doesn't:

The order of allocation of
bit-fields within a unit (high-order to low-order or low-order
to high-order) is implementation-defined.


Have you actually noticed differences in behaviour between compilers
targeting the same processor?

Well, no. I tend to choose a compiler and stick to it. (Recently I
have been using gcc for everything). I expect you're right (that most
compilers for the same platform have the same bit allocations). I just
read somewhere not to use bitfields for this sort of thing, when I was
learning C. And I never did. I end up with constructs like

REG |= 3<<1 | 1<<3 | 1<<6;

etc.
 
T

The real OS2 guy

I've not, still I know that there are such systemsi, and I'm about to
experience such systems in the near future.

I probably should have mentioned the even smaller systems, but I have or
had the feeling that the number of such systems is rather low, when one
comes to think about this in more depth, one recognizes that feelings
are not always to be trusted. ;-)

For that it is much easier to maintenace a structure of bitfields than
to crawl through the whole soure to find thouseds of bitmasks, shit
operations and so on:

#ifdef MASHINEA
typedef struct S_A {
unsigned s : 1;
unsigned f : 3;
unsigned v : 4;
unsigned ta : 4;
unsigned tb : 4;
unsigned reserve : 16; /* planned hardware extension */
} *PREGC;

In question it is siple to reorder the struct and forget the access to
spezific bits:
#elseif MASHINEB
typedef struct S_A {
unsigned reserve : 4; /* planned hardware extension! */
unsigned tb : 4;
unsigned ta : 4;
unsigned reserve2 :4;
unsigned v : 4;
unsigned reserve3 :8;
unsigned f : 3;
unsigned s : 1;
} *PREGC;
#else /* mashine C */
.....

and all changes are done, each bitfield gets addressed with its own
name instead some shift macros, fiddeling around with masks and son
on. A simple assignment, a simple test is what is visible in the
soure. Let the compiler do the mashine dependant work, simply do the
project work.

#define RESET_REGC 0xf
#define INIT_REGC 0x0
......


PREGC regc = (PREGC) REGC_ADDR;
......
if (regc->v) ra = regc->ta, regc->tb = ro, regc->s = 0;
else regc->v = regc->s ? RESET_REGC : INIT_REGC;

ist doch einiges übersichtlicher als

temp = *r4711 & REGC_MASK_V >> REGC_V_SHIFT_COUNT;
if (temp)
ra = temp & REGC_MASK_TA >> ......
......
oder sonstige Makrobastelei.


Bitfelder sind nicht auf allen Maschinenstrukturen identisch
organisiert - aber selbst bei kleineren Hardwareabweichungen lassen
sich durch geschickt gewählte structs, die eben die Bits
(maschinenabhängig sortiert) Bitfeler ausweisen einfacher im Source
handhaben, ohne Rücksicht auf die konkrete Maschine.

Treiber, die auf einer Maschine eine ganze Familie von Geräten mit
vendorspezifischen Abweichungen behandeln, lassen sich so auch auf
einen lesbaren Codelevel bringen. Wenn kein Hardwareregister drunter
steckt, lassen sich auch ganze Flagorgien kompakt organisieren - ohne
mit casting, shiftorgien und Makrogeschwüren rumzumachen.

Klarer, lesbarer Code ist wichtiger als Speicher und Laufzeitersparnis
im Mikrosekundenbereich. Und wenn es wirklich auf die Nanosekunde und
das letzte Byte Codeersparnis ankommt, hilft sowieso nur noch
Unportabilität in aller Konsequenz == Assebler. Ansonsten
höchstmögliche Portabilität, einfacher Code, Klarheit und damit
Bitfelder wo möglich/nötig.

Bitfelder helfen maßgeblich dabei.



--
Tschau/Bye

Herbert Rosenau
http://www.pc-rosenau.de eComStation Reseller in Germany
eCS 1.1 german is in beta testing
 
C

Chris Torek

Have you actually noticed differences in [bit-field] behaviour
between compilers targeting the same processor?

I have.

The MIT 68k C compiler used little-endian bit ordering, while the
Sun 68k C compiler on the Sun 2 used big-endian ordering.

These did both predate ANSI C, but since 1993 or so I have had the
luxury of using only a single C compiler (GCC). (I suppose GCC
could be called many different compilers; certainly gcc1, gcc2,
egcs, and now gcc3 have all been rather different internally. But
they are more like each other than they are like the old VAX PCC,
for instance.)
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,768
Messages
2,569,574
Members
45,050
Latest member
AngelS122

Latest Threads

Top