Quote:
>Huh.. Why on earth did the ANSI-C makers dicide to consider the
>'uchar a:4' as an invalid one. It seams to me that they did
There is insufficient utility in standardizing bit fields other than int or
unsigned int.
What is the use of a bit-field that is an unsigned char? All that means is
that it can't be wider than CHAR_BIT.
Quote:
>think if the 'bitfields of an int' are valid, then the 'bitfields
>of char' should be valid ones. Like if there exists an 'unsigned
>int', the existence of 'an unsigned char' is natural one. For me
>the bitfields of char is very important because I have to control
>each bit pattern of a register in a board. For example, for
>the following a register, I am in a situation of controlling
>each bit at my will,
>+------+------+------+------+------+------+------+------+
>| W2 | W1 | W0 | INTR | DMA | PORT2|PORT1 |PORT0 |
>| | | | | | | | |
>+------+------+------+------+------+------+------+------+
Since you are accessing hardware, you are no longer writing in portable
C. Using bit-fields to correspond to an external storage layout is
highly non-portable. You might as well use GCC's extension of allowing
unsigned char bitfields.
Quote:
>And I imagined that if I create a structure like follwoing,
>struct some_register {
> uchar_t r_wait:3,
> r_intr:1,
> r_dma:1,
> r_port:3;
>};
The GNU compiler supports this as an extension, but warns if you use the -ansi
flag. It so happens that GCC is able to produce a structure of size 1 if all
it contains is an unsigned char bitfield. However, don't expect this to be
portable to other compilers.
Quote:
>them I can manipulate the reigster easily. Therfore your statement
>that the bitfield of a char are invalid ones makes me disappointed,
>and makes me complain to people who made ANSI-C. I dare to think
It's noteworthy that C++ does not have this restriction, so maybe
you should consider compiling your program with g++. :)
Quote:
>that 'the bitfields of a char' are much much more useful ones than
>'those of an int'.
That depends on what you mean by ``useful''. In the broader context
of C programming, what is useful is that which is portable.
There is no semantic advantage in declaring a member
unsigned char x : 8;
versus
unsigned x : 8;
Both of them have the same range of values, and there is no guarantee
that the non-portable variant will use less storage. If the C committee
changed the language to allow unsigned char to be a base type for a bit-field,
I doubt that they would impose additional requirements that bitfields
of a smaller type should occupy less space than bitfields of a larger type.
You can see this usefulness of 'bitfields of
Quote:
>char' in the ip structure of /usr/include/netinet/ip.h. You can
The implementation-supplied headers don't have to obey the rules of
the language. They don't even have to be source files.
I could make the same argument about any GCC extension that is used
in Linux header files: see how useful it is to mark a non-returning
function with a suitable __attribute__ ((noreturn)) ? It should
be in the language!
All I see is a header file that fails to conform to the C language,
and which makes it potentially difficult to use some source code tools which
operate pre-processed output, and expect to be able to parse the output using
the ANSI C grammar and ANSI C constraint checks.
Quote:
>find a lot of examples at that directory if you are unsing a
>unix machine.
Which types of UNIXes have you investigated for this?
Quote:
>Is there anybody who has ever made the 'bitfields'
>of an int? I have never met a situation in which the bitfields of
>int might be useful ones because I can easily split up an integer
>into 'char, or short', and I have never met a source code that was
>coded using the 'bitfields of int'.
The idea behind bit-fields is that adjacent bit-fields may be packed
together to save space. For the purpose of packing, the type is largely
irrelevant; the type specifier serves only to constrain the size.
It is the bit field size that is important.
ANSI C makes it a constraint violation if the bit field width exceeds
the size of the bit-field's type, even if that type is other than int.
I've used bitfields of unsigned int type quite frequently, for example to save
space in representing various object flags:
struct connection {
unsigned allocated : 1;
unsigned connected : 1;
unsigned direction : 2;
};
Such declarations are written in the hope that the bitfields will be packed
into a single unit of storage to save space, at the possible cost of access
time. The size of the unit of storage is implementation-defined, and as such
is of little interest in portable coding situations.
In GCC, the _only_ advantage you gain by using an unsigned char bitfield
is that the compiler will use a smaller unit size for allocating the
bitfields, so that accessing a bitfield causes a single byte memory
transfer, rather than a word memory transfer (on machines that support
byte transfers, of course).
There are some additional things you might want to know about bitfields.
You can have unnamed bitfields:
unsigned : 2;
These serve the purpose of padding. You can also have unnamed bitfields
of size zero:
unsigned : 0;
The purpose of these is to force the _next_ bitfield to lie in a new
storage unit rather than be packed into the previous storage unit.
Also, it is implementation-defined whether a bitfield can straddle two
adjacent storage units. For example, if the storage unit is 16 bits
wide, it is implementation defined whether
unsigned a : 15;
unsigned b : 3;
will place the b into the next storage unit, or whether it will put one bit
of it into the first storage unit, and two bits into the next. However,
if you write
unsigned a : 15;
unsigned : 0;
unsigned b : 3;
you can be sure that the b will go into the new storage unit.