define a data type of 1 bit size

A

Angel Lopez

Sorry if I am too naive, but this is my first post...
I have a binary variable (it can contain either a 0 or a 1).
Is there any way I can define a data type that uses only 1 bit. So
far I have defined it as a char variable. I've searched everywhere but
I don't seem to find any place that explains how to define this type
of data type. The closest thing I've found are bit fields in
structures, I would like something like bit fields but without the
structure.
something like
unsigned MyVariable :1;
Thanks,
Angel
 
A

Alex Fraser

Angel Lopez said:
Sorry if I am too naive, but this is my first post...
I have a binary variable (it can contain either a 0 or a 1).
Is there any way I can define a data type that uses only 1 bit. So
far I have defined it as a char variable. I've searched everywhere but
I don't seem to find any place that explains how to define this type
of data type. The closest thing I've found are bit fields in
structures, I would like something like bit fields but without the
structure.

If you don't have too many of them, using a built-in type such as char or
even int is fine - just use zero for 0 and non-zero for 1.

If you want lots (and lots) of them in an array, you can save memory and
perhaps get better performance by using an unsigned type such as unsigned
int and writing simple functions or macros to access them by specifying a
bit index. The optimal type will depend on the platform, but it's easy to
write code so you can change the type to experiment if and when you find
performance to be a problem.

Compilers for some microcontrollers (such as 8051-alikes) have extensions to
the language that allow you to define bit variables. Bit variables are
typically more useful in these embedded environments where memory may be
very limited.

Alex
 
J

jacob navia

Angel said:
Sorry if I am too naive, but this is my first post...
I have a binary variable (it can contain either a 0 or a 1).
Is there any way I can define a data type that uses only 1 bit. So
far I have defined it as a char variable. I've searched everywhere but
I don't seem to find any place that explains how to define this type
of data type. The closest thing I've found are bit fields in
structures, I would like something like bit fields but without the
structure.
something like
unsigned MyVariable :1;
Thanks,
Angel
In C99 you can write:
#include <stdbool.h>

bool myvar = 1;

This will take a char (8 bits). You can't address bits so this will be
the same in all compilers. The advantage is that if you write
myvar=78;
printf("%d\n",myvar);
that will print 1 and not 78.

jacob
 
M

Merrill & Michele

MVC++6 allows a boolean type which will port almost nowhere and takes up a
byte anyways. Although I've never laid eyes on ANSI, I thought the deal was
that bytes always have eight bits and all data types are a multiple of
bytes. You could certainly write a program to squeeze eight ones or zeros
into a byte, but I think it's a stretch to call what results a proper data
type. MPJ
 
J

Jack Klein

In C99 you can write:
#include <stdbool.h>

bool myvar = 1;

This will take a char (8 bits). You can't address bits so this will be
the same in all compilers. The advantage is that if you write

No, this will be at least sizeof(char), which is 8 bits on most
platforms but larger on others. And there are some implementations
that use (un)signed ints for _Bool.

What is the same on all compilers is that you cannot have any objects
smaller than one byte in size, however many bits a byte may contain.
 
J

Jack Klein

Sorry if I am too naive, but this is my first post...
I have a binary variable (it can contain either a 0 or a 1).
Is there any way I can define a data type that uses only 1 bit. So
far I have defined it as a char variable. I've searched everywhere but
I don't seem to find any place that explains how to define this type
of data type. The closest thing I've found are bit fields in
structures, I would like something like bit fields but without the
structure.
something like
unsigned MyVariable :1;
Thanks,
Angel

This just can't be done in C. Bit-fields are only allowed inside
structures, and other than bit-fields, no object is allowed to be
smaller than sizeof(char).

If you actually have a large enough number of these values that memory
space becomes important, the FAQ for this group has an example of
packing multiple bits into larger data types.

See http://www.eskimo.com/~scs/C-faq/q20.8.html
 
J

Jack Klein

On Mon, 6 Sep 2004 10:32:09 -0500, "Merrill & Michele"

First, don't top-post. Material you add in a reply belongs after
quoted material you are commenting on. If you don't want to get a
real newsreader, use Google to search for a patch to Outlook Express
that defaults the entry point in replies to the proper location.

MVC++6 allows a boolean type which will port almost nowhere and takes up a
byte anyways. Although I've never laid eyes on ANSI, I thought the deal was
that bytes always have eight bits and all data types are a multiple of
bytes. You could certainly write a program to squeeze eight ones or zeros
into a byte, but I think it's a stretch to call what results a proper data
type. MPJ

You thought wrong. A byte in C contains CHAR_BIT bits, this macro
defined in <limits.h>. It must be at least 8, but may be more and is
16 or 32 on some implementations.

You were right about the fact that all objects must be a multiple, 1
or more, of sizeof(char).
 
B

Ben Noordhuis

Merrill & Michele said:
Although I've never laid eyes on ANSI, I thought the deal was
that bytes always have eight bits and all data types are a multiple of
bytes.

ANSI guarantees that "char" has _at least_ eight bits. Moreover, it
guarantees that a "char *" can access _any_ bit in memory[1].

Bear with me.

For example, on the 80x86 architecture memory is divided in the eight
bit chunks we've all come to know and love as "bytes". So "char" does
the sensible thing and defaults to eight bits also [2].

Now, let's take the PDP-10. This strange beast has it's memory divided
into 36 bits words. If "char" would've been eight bits, we wouldn't be
able to access (36 % 8) = 4 bits per word, which is _bad_.
So, as a work-around, "char" consists of nine bits and all is well
again because (36 % 9) = 0.

On a final note, don't use bit fields. There are a lot of compilers
out there that don't support them (properly)

Ben Noordhuis

[1] I'm obviously not taking MMU restrictions in account here ;-)
[2] Please note that "sensible" doesn't mean "mandatory". It would be
perfectly legal for a x86-compiler to use 32 bits for "char" instead.
 
M

Merrill & Michele

What does a fella do? On the one hand, I'm told that I'm posting
improperly. On the other, I can't discern my lack of net nuchego without
observing my own posts.

We need to discuss this issue, as, in my belief, it does not arise in FAQ's.
If a single person posts under me witgh an opinion that a data type has less
than 8 bits, then you need to come to grips with the legacy of LeRoy Wentz.

MPJ
 
C

CBFalconer

Merrill said:
What does a fella do? On the one hand, I'm told that I'm posting
improperly. On the other, I can't discern my lack of net nuchego
without observing my own posts.

Before you go any further correct your top-posting habit. Your
reply goes after, or intermixed with, the quoted material, AFTER
snipping out anything that is not germane to your reply. That way
each article is readable and stands more or less by itself.
 
K

Keith Thompson

Although I've never laid eyes on ANSI, I thought the deal was
that bytes always have eight bits and all data types are a multiple of
bytes.

ANSI guarantees that "char" has _at least_ eight bits. Moreover, it
guarantees that a "char *" can access _any_ bit in memory[1]. [footnote moved up]
[1] I'm obviously not taking MMU restrictions in account here ;-)

A "char *" can access any byte of any accessible object. For any byte
outside an accessible object (either a declared object or one
allocated by malloc(), calloc(), or realloc()), all bets are off.

[...]
On a final note, don't use bit fields. There are a lot of compilers
out there that don't support them (properly)

I don't know of any C compilers that don't support bit fields
properly. The layout isn't guaranteed to be consistent from one
compiler to another, but there's no such guarantee for ordinary struct
members either.
 
D

Dan Pop

In C99 you can write:
#include <stdbool.h>

bool myvar = 1;

This will take a char (8 bits).

Can I have a chapter and verse for this?
You can't address bits so this will be the same in all compilers.
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Ditto.
The advantage is that if you write
myvar=78;
printf("%d\n",myvar);
that will print 1 and not 78.

You don't need any C99 features for that:

int myvar = 78;
printf("%d\n", !!myvar);

For individual boolean variables, int is usually the best choice (there
are platforms where accessing char's has additional overheads). It's
only when you have to deal with *large* amounts of booleans that you need
to start thinking about saving space.

Dan
 
D

Dan Pop

In said:
[email protected] (Ben Noordhuis) said:
Although I've never laid eyes on ANSI, I thought the deal was
that bytes always have eight bits and all data types are a multiple of
bytes.

ANSI guarantees that "char" has _at least_ eight bits. Moreover, it
guarantees that a "char *" can access _any_ bit in memory[1]. [footnote moved up]
[1] I'm obviously not taking MMU restrictions in account here ;-)

A "char *" can access any byte of any accessible object.

Nope, only "unsigned char *" has this property. Plain char may not be
able to access full bytes (due to the padding bits issues).

Dan
 
B

Ben Noordhuis

Keith Thompson said:
ANSI guarantees that "char" has _at least_ eight bits. Moreover, it
guarantees that a "char *" can access _any_ bit in memory[1].
[1] I'm obviously not taking MMU restrictions in account here ;-)

A "char *" can access any byte of any accessible object. For any byte
outside an accessible object (either a declared object or one
allocated by malloc(), calloc(), or realloc()), all bets are off.

True. I should've mentioned that as well. Stupid me.
I don't know of any C compilers that don't support bit fields
properly. The layout isn't guaranteed to be consistent from one
compiler to another, but there's no such guarantee for ordinary struct
members either.

Trust me on this one: on some of the more exotic
architectures/compilers bit fields cause all sorts of weird behavior,
if they are supported at all. Use the &, | and ^ operators and all is
well again.

I've had some rather frustrating experiences with this. The reason I'm
not really sure about but my best bet is that the original compiler
didn't support bit fields and had them patched in later on (but alas,
not too well). I've heard similar stories from friends working on
another architecture.
Of course, this means the compiler is broken, not the Standard. But
it's little trouble to AND, OR and XOR yourself.
 
D

Dan Pop

In said:
Trust me on this one: on some of the more exotic
architectures/compilers bit fields cause all sorts of weird behavior,
if they are supported at all.

We don't care about compilers that do not implement any of the common
C specifications: K&R, C89, C99. All these specifications require
support for bit fields and define their behaviour, up to a couple of
issues (order of allocation and the semantics of plain int).
Of course, this means the compiler is broken, not the Standard. But
it's little trouble to AND, OR and XOR yourself.

It makes a huge difference in the code readability. Especially when
you have to deal with someone else's code...

Of course, if you're forced to use broken tools, you may have no choice,
but until then, there is no point in avoiding bit fields.

The real issue with them is that you cannot *portably* map a certain
bit layout with bit fields, which is a pity, because certain protocols
and hardware interfaces are defined in terms of bit fields. So,
maximally portable code must perform conversions between the internal
bit field layout (which is under compiler control) and the external
bit field layout (which is specified by the application).

Dan
 
K

Keith Thompson

Trust me on this one: on some of the more exotic
architectures/compilers bit fields cause all sorts of weird behavior,
if they are supported at all. Use the &, | and ^ operators and all is
well again.

Do you have examples?

Bit fields have been part of the core language since before K&R1 was
published. (I'm actually not sure when they were introduced.) If a
compiler didn't support them properly, I wouldn't trust it to do
anything else correctly either. It could as easily have implemented
bit fields correctly but had some subtle bugs in the implementation of
the &, |, and ^ operators (though those are admittedly easier to get
right). Perhaps you were using a compiler that was still under
development.

Another thing to keep in mind is that bit fields are often misused.
The only valid types for a bit field are unsigned int, signed int, and
int (which may be treated as either signed or unsigned) (and bool or
_Bool in C99). And of course the only guarantee is that you'll get
back what you stored in them; they can't be used reliably to control
layout.

As Dan wrote, if you're stuck with a broken or incomplete compiler,
you may have to use a few workarounds, but it's unwise to let those
workarounds influence the way you write code for *real* compilers.
The standard is a contract between the implementer and the programmer;
it exists so programmers can safely assume that certain things will
work in certain ways.
 
B

Ben Noordhuis

Keith Thompson said:
Do you have examples?

Bit fields have been part of the core language since before K&R1 was
published. (I'm actually not sure when they were introduced.) If a
compiler didn't support them properly, I wouldn't trust it to do
anything else correctly either. It could as easily have implemented
bit fields correctly but had some subtle bugs in the implementation of
the &, |, and ^ operators (though those are admittedly easier to get
right). Perhaps you were using a compiler that was still under
development.

The code was meant to run on an embedded system using a stripped down
386SX with a reduced instruction set. The compiler used was "pcc"
IIRC, targeted for cross-compilation. It had a few bugs, some more
subtle than others, but they were all fairly well documented.
Except for the trouble with bit fields.
But yes, if it wasn't in the development stage, it was at least a case
of "work in progress".

I've heard of a few other people complaining about problems with bit
fields as well but I don't know which architecture/compiler they
were/are using.
Another thing to keep in mind is that bit fields are often misused.
The only valid types for a bit field are unsigned int, signed int, and
int (which may be treated as either signed or unsigned) (and bool or
_Bool in C99). And of course the only guarantee is that you'll get
back what you stored in them; they can't be used reliably to control
layout.

Of which I am aware :)
As Dan wrote, if you're stuck with a broken or incomplete compiler,
you may have to use a few workarounds, but it's unwise to let those
workarounds influence the way you write code for *real* compilers.
The standard is a contract between the implementer and the programmer;
it exists so programmers can safely assume that certain things will
work in certain ways.

Yes and no.

Yes, as in: a compiler calling itself "ANSI C" should conform to the
Standard. Not just loosely but entirely, so programmers know what to
expect. That's what the Standard is for.

No, as in: it's no effort to use the bit-wise operators instead of bit
fields and if my code becomes just that little bit (no pun intended)
more portable by doing so, why refrain from it?
 
M

Merrill & Michele

Aha--so this is what you're getting at. (Continued below)
Before you go any further correct your top-posting habit. Your
reply goes after, or intermixed with, the quoted material, AFTER
snipping out anything that is not germane to your reply. That way
each article is readable and stands more or less by itself.

--
"I'm a war president. I make decisions here in the Oval Office
in foreign policy matters with war on my mind." - Bush.
"If I knew then what I know today, I would still have invaded
Iraq. It was the right decision" - G.W. Bush, 2004-08-02

Is this a correct posting? MPJ
 
C

CBFalconer

Merrill said:
Aha--so this is what you're getting at. (Continued below)


Is this a correct posting? MPJ

Much better, except you neglected to snip. For example my sig
above (everything following the "-- " line inclusive) should go.
It stays here because I am referring to it, and without it my
reply would not make sense.
 
A

Arthur J. O'Dwyer

Aha--so this is what you're getting at. (Continued below)

/What/ is "what you're getting at"? Your "reply" doesn't seem to
follow from the "context." You need to quote some context, so that
your posts follow some sort of logical, conversational,
question-and-answer style.
Is this a correct posting? MPJ

No. You need to learn to put your responses following the material
to which you're responding. For crying out loud, just look at the
way /every other person in this newsgroup/ does it! It's not like it's
some mystical thing you have to be trained in!
And snip sigs if they're not relevant to your post. Snip /anything/
that's not relevant to your post. Just like every other person in this
newsgroup.
Read the archives if you're having trouble.

HTH,
-Arthur
 

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

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,580
Members
45,055
Latest member
SlimSparkKetoACVReview

Latest Threads

Top