First of all, there's no storage associated with your macros; they expand to the integer constants 0
and 1
. The sizeof
evaluates to 4 because the expressions have integer type. You can certainly assign those values to objects of smaller type (short
or char
).
For me, life got a lot simpler when I stopped using TRUE
and FALSE
macros1. Remember that in C, a zero-valued integral expression evaluates to false, and all non-zero-valued integral expressions evaluate to true.
If you want to store values into something smaller than 8 bits, then you're going to have to do your own bit packing, something like
#define TEST(x,bit) ((x) & (1 << (bit)))
#define SET(x,bit) ((x) |= (1 << (bit)))
#define CLEAR(x,bit) ((x) &= ~(1 << (bit)))
The smallest useful type for this is unsigned char
. So if you need to store N single-bit values, you need an array of N/CHAR_BIT+1 elements. For example, to store 10 single-bit boolean values, you need 2 eight-bit array elements. Bits 0 through 7 will be stored in element 0, and bits 8 through 10 will be stored in element 1.
So, something like
#define MAX_BITS 24
unsigned char bits[MAX_BITS / CHAR_BIT + 1];
int bit = ...;
SET(bits[bit/CHAR_BIT], bit % CHAR_BIT);
if ( TEST(bits[bit/CHAR_BIT], bit % CHAR_BIT) )
{
// do something if bit is set
}
CLEAR(bits[bit/CHAR_BIT], bit % CHAR_BIT);
No warranties express or implied; I don't do a lot of bit twiddling. But hopefully this at least points you in the right direction.
1. The precipitating event was someone dropping a header where TRUE
== FALSE
. Not the most productive afternoon.