Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C Programming > Bit-fields in unsigned short

Reply
Thread Tools

Bit-fields in unsigned short

 
 
dspfun
Guest
Posts: n/a
 
      03-09-2011
Hi,

I want to use bit-fields in unsigned short types since it makes code a
lot easier to read and I don't have to do bit-masks and bit-shifts to
access the individual bit-fields.

However, it seems as C99 only allows bit-fields for unsigned char and
unsigned int, and bit-fields in unsigned short is a GCC extension.

I get the following compilation warning

>gcc -Wall -pedantic bit_field_unsigned_short_test.c

bit_field_unsigned_short_test.c:6: warning: type of bit-field 'field1'
is a GCC extension
bit_field_unsigned_short_test.c:7: warning: type of bit-field 'field2'
is a GCC extension
bit_field_unsigned_short_test.c:8: warning: type of bit-field 'field3'
is a GCC extension

When I compile the following code:


>gcc -Wall -pedantic bit_field_unsigned_short_test.c

bit_field_unsigned_short_test.c: In function 'main':
bit_field_unsigned_short_test.c:8: warning: type of bit-field 'field1'
is a GCC extension
bit_field_unsigned_short_test.c:9: warning: type of bit-field 'field2'
is a GCC extension
bit_field_unsigned_short_test.c:10: warning: type of bit-field
'field3' is a GCC extension

How can I use bitfields in unsigned short without getting the warnings
about bit-fields and still use -pedantic flag?

Brs,
Markus
 
Reply With Quote
 
 
 
 
Ben Bacarisse
Guest
Posts: n/a
 
      03-09-2011
dspfun <(E-Mail Removed)> writes:

> I want to use bit-fields in unsigned short types since it makes code a
> lot easier to read and I don't have to do bit-masks and bit-shifts to
> access the individual bit-fields.


It's worth noting that the semantics are different. Using shifts and/or
masks gives you sequences of bits with known value or significance
whereas how bit-fields are packed into a struct is up to the compiler.
This does not matter so much if your code if aimed at one compiler only,
but you still need to take care that compiler options (or versions)
don't affect the packing.

> However, it seems as C99 only allows bit-fields for unsigned char and
> unsigned int, and bit-fields in unsigned short is a GCC extension.


C99 allow lots of types but it only insists that an implementation
support _Bool along with signed and unsigned int.

> I get the following compilation warning
>
>>gcc -Wall -pedantic bit_field_unsigned_short_test.c

> bit_field_unsigned_short_test.c:6: warning: type of bit-field 'field1'
> is a GCC extension
> bit_field_unsigned_short_test.c:7: warning: type of bit-field 'field2'
> is a GCC extension
> bit_field_unsigned_short_test.c:8: warning: type of bit-field 'field3'
> is a GCC extension


That's probably not compiling in C99 mode, by the way.

> When I compile the following code:
>
>>gcc -Wall -pedantic bit_field_unsigned_short_test.c

> bit_field_unsigned_short_test.c: In function 'main':
> bit_field_unsigned_short_test.c:8: warning: type of bit-field 'field1'
> is a GCC extension
> bit_field_unsigned_short_test.c:9: warning: type of bit-field 'field2'
> is a GCC extension
> bit_field_unsigned_short_test.c:10: warning: type of bit-field
> 'field3' is a GCC extension
>
> How can I use bitfields in unsigned short without getting the warnings
> about bit-fields and still use -pedantic flag?


What advantage do you hope to get from using unsigned short rather than
unsigned int for bit-fields? I can't see why you don't want to use
unsigned int as the type.

--
Ben.
 
Reply With Quote
 
 
 
 
dspfun
Guest
Posts: n/a
 
      03-09-2011
On 9 mar, 10:40, Ben Bacarisse <(E-Mail Removed)> wrote:
> What advantage do you hope to get from using unsigned short rather than
> unsigned int for bit-fields? *I can't see why you don't want to use
> unsigned int as the type.


The reason is that two bytes are sent from a big endian cpu and "we"
receive it on a little endian cpu. To access the information in the
two bytes I declare a struct with bit-fields.

Brs,
Markus

 
Reply With Quote
 
Jens
Guest
Posts: n/a
 
      03-09-2011
On 9 Mrz., 14:34, dspfun <(E-Mail Removed)> wrote:

> The reason is that two bytes are sent from a big endian cpu and "we"
> receive it on a little endian cpu. To access the information in the
> two bytes I declare a struct with bit-fields.


Don't do that. There are appropriate macros hton and ntoh for that
purpose already.

Jens
 
Reply With Quote
 
James Kuyper
Guest
Posts: n/a
 
      03-09-2011
On 03/09/2011 08:34 AM, dspfun wrote:
> On 9 mar, 10:40, Ben Bacarisse<(E-Mail Removed)> wrote:
>> What advantage do you hope to get from using unsigned short rather than
>> unsigned int for bit-fields? �I can't see why you don't want to use
>> unsigned int as the type.

>
> The reason is that two bytes are sent from a big endian cpu and "we"
> receive it on a little endian cpu. To access the information in the
> two bytes I declare a struct with bit-fields.


The standard deliberately under-specifies the layout of structs, and
this is particularly true for bit fields. As a result, you cannot
portably rely upon the bits from the data you're transferring being in
the same location as the bits corresponding to any particular bit field.
If portability isn't an issue, then there's no problem; but for
maximally portable code, your best option is to use a unsigned char
buffer, and extracting the bits by using shift and mask operations.

This still isn't perfect: such code usually relies upon CHAR_BITS==8,
which is also not guaranteed. However, you can at least check at compile
time whether CHAR_BITS==8, and chose an appropriate alternative if it is
not. You cannot determine at compile time which bits of a struct
correspond to a given bit field, though there are ways to do so at run time.

--
James Kuyper
 
Reply With Quote
 
Ben Bacarisse
Guest
Posts: n/a
 
      03-09-2011
dspfun <(E-Mail Removed)> writes:

> On 9 mar, 10:40, Ben Bacarisse <(E-Mail Removed)> wrote:
>> What advantage do you hope to get from using unsigned short rather than
>> unsigned int for bit-fields? *I can't see why you don't want to use
>> unsigned int as the type.

>
> The reason is that two bytes are sent from a big endian cpu and "we"
> receive it on a little endian cpu. To access the information in the
> two bytes I declare a struct with bit-fields.


That does not help me to see why you think unsigned short will be better
than unsigned int for the bit-field. Can you show a fragment of code,
for example, or show what you used to do until you started to consider
using unsigned short bit-fields?

--
Ben.
 
Reply With Quote
 
Ben Bacarisse
Guest
Posts: n/a
 
      03-09-2011
Kenneth Brody <(E-Mail Removed)> writes:
<snip>
> It may be worth noting that which bits are used for bit-fields is
> implementation-defined.
>
> 6.7.2.1p10:
>
> The order of allocation of bit-fields within a unit (high-order
> to low-order or low-order to high-order) is implementation-defined.
>
> I found this out the hard way some 25+ years ago when porting a
> program which stored flags in bit-fields, and saved the value to a
> file. It worked fine until the program was ported to a system which
> allocated bits the other way.


A nit-pick if I may... The problem is that the program saved the
representation rather than the value -- i.e. that it wrote out the bytes
used by the implementation rather than what they denoted.

It is possible to store the value of a structure that uses bit-fields in
a portable manner (by using printf, for example) though the very use of
bit-fields often suggests an interest in speed and compactness at odds
with doing so. I suspect that a high proportion of the time, that
interest is misplaced!

<snip>
--
Ben.
 
Reply With Quote
 
dspfun
Guest
Posts: n/a
 
      03-10-2011
On 9 mar, 14:59, Ben Bacarisse <(E-Mail Removed)> wrote:

> That does not help me to see why you think unsigned short will be better
> than unsigned int for the bit-field. *Can you show a fragment of code,
> for example, or show what you used to do until you started to consider
> using unsigned short bit-fields?


The data sent from the first CPU is actually 32 bit (unsigned int) and
on the receiving CPU these 32 bit are casted to a struct with two
unsigned char (8 bit) and one unsigned short (16 bit).

I agree with you that it would be better to use a struct with bit-
fields of an unsigned int (32 bit).

Thanks for your help!

Brs,
Markus

 
Reply With Quote
 
dspfun
Guest
Posts: n/a
 
      03-10-2011
On 9 mar, 17:57, Ben Bacarisse <(E-Mail Removed)> wrote:
> Kenneth Brody <(E-Mail Removed)> writes:
>
> <snip>
>
> > It may be worth noting that which bits are used for bit-fields is
> > implementation-defined.

>
> > 6.7.2.1p10:

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

>
> > I found this out the hard way some 25+ years ago when porting a
> > program which stored flags in bit-fields, and saved the value to a
> > file. *It worked fine until the program was ported to a system which
> > allocated bits the other way.

>
> A nit-pick if I may... *The problem is that the program saved the
> representation rather than the value -- i.e. that it wrote out the bytes
> used by the implementation rather than what they denoted.
>
> It is possible to store the value of a structure that uses bit-fields in
> a portable manner (by using printf, for example) though the very use of
> bit-fields often suggests an interest in speed and compactness at odds
> with doing so. *I suspect that a high proportion of the time, that
> interest is misplaced!
>


How do you store the value of a structure that uses bit-fields in a
portable manner?

For example, the following file uses bit-fields and not masks and
shifts. Is this according to the C99-standard or implementation
defined?

/usr/src/linux-2.6.16.60-0.69.1/include/linux/ip.h

struct iphdr {
#if defined(__LITTLE_ENDIAN_BITFIELD)
__u8 ihl:4,
version:4;
#elif defined (__BIG_ENDIAN_BITFIELD)
__u8 version:4,
ihl:4;
#else
#error "Please fix <asm/byteorder.h>"
#endif
__u8 tos;
__be16 tot_len;
__be16 id;
__be16 frag_off;
__u8 ttl;
__u8 protocol;
__u16 check;
__be32 saddr;
__be32 daddr;
/*The options start here. */
};
 
Reply With Quote
 
Ben Bacarisse
Guest
Posts: n/a
 
      03-10-2011
dspfun <(E-Mail Removed)> writes:

> On 9 mar, 14:59, Ben Bacarisse <(E-Mail Removed)> wrote:
>
>> That does not help me to see why you think unsigned short will be better
>> than unsigned int for the bit-field. *Can you show a fragment of code,
>> for example, or show what you used to do until you started to consider
>> using unsigned short bit-fields?

>
> The data sent from the first CPU is actually 32 bit (unsigned int) and
> on the receiving CPU these 32 bit are casted to a struct with two
> unsigned char (8 bit) and one unsigned short (16 bit).


I know what you mean, but you can't cast to a struct type.

> I agree with you that it would be better to use a struct with bit-
> fields of an unsigned int (32 bit).


A bit-field of type unsigned int is better than a bit-field of type
unsigned short but I have not said (and I would not say) that you should
use a struct with bit-fields over the one you describe first! You seem
to be taking a step backwards by using bit-fields for any sort.

If you need the code to be portable and to deal with different machine
representations, then using a struct at all is not a good way to impose
a meaning on a block of data. Since you are talking about sending and
receiving and have mentioned endianness already, I think you may have
started by asking the wrong question.

--
Ben.
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
(int) -> (unsigned) -> (int) or (unsigned) -> (int) -> (unsigned):I'll loose something? pozz C Programming 12 03-20-2011 11:32 PM
unsigned short, short literals Ioannis Vranos C Programming 5 03-05-2008 01:25 AM
How to combine 2 unsigned short into a unsigned int? fancyerii Java 21 11-05-2007 09:33 PM
longs, long longs, short short long ints . . . huh?! David Geering C Programming 15 01-11-2007 09:39 PM
unsigned short short? slougheed@gmail.com C++ 4 10-16-2006 11:25 PM



Advertisments