Velocity Reviews

Velocity Reviews (http://www.velocityreviews.com/forums/index.php)
-   C Programming (http://www.velocityreviews.com/forums/f42-c-programming.html)
-   -   bitfields in union : defined behaviour ? (http://www.velocityreviews.com/forums/t440767-bitfields-in-union-defined-behaviour.html)

gert.vierman@gmail.com 01-05-2006 09:41 AM

bitfields in union : defined behaviour ?
 
Hello,

Here is some code mixing bitfields and longs in an union.
Any comments on the validity and portability of this program ?
Thank you very much.

#include <stdio.h>

union msg_t {

struct elem {
unsigned long foo: 16;
unsigned long bar: 12;
unsigned long type: 4;
unsigned long length: 32;
} elem;

unsigned long data[2];

} ;

int main(int argc, char **argv)
{
union msg_t msgh;

msgh.elem.bar = 0x2;
msgh.elem.foo = 0x3;
msgh.elem.length = 0x100;

printf("%08x\n", msgh.data[0]);
printf("%08x\n", msgh.data[1]);

return 0;
}


gert.vierman@gmail.com 01-05-2006 10:14 AM

Re: bitfields in union : defined behaviour ?
 

gert.vierman@gmail.com wrote:
> Hello,
>
> Here is some code mixing bitfields and longs in an union.
> Any comments on the validity and portability of this program ?
> Thank you very much.
>
> #include <stdio.h>
>
> union msg_t {
>
> struct elem {
> unsigned long foo: 16;
> unsigned long bar: 12;
> unsigned long type: 4;
> unsigned long length: 32;
> } elem;
>
> unsigned long data[2];
>
> } ;
>
> int main(int argc, char **argv)
> {
> union msg_t msgh;
>
> msgh.elem.bar = 0x2;
> msgh.elem.foo = 0x3;
> msgh.elem.length = 0x100;
>
> printf("%08x\n", msgh.data[0]);
> printf("%08x\n", msgh.data[1]);
>
> return 0;
> }


I am sorry, all 'unsigned longs' should be replaced by the proper type
which is guaranteed to be an unsigned 32 bits int on all platforms.
maybe uint32_t from stdint.h ?


Richard Bos 01-05-2006 01:56 PM

Re: bitfields in union : defined behaviour ?
 
gert.vierman@gmail.com wrote:

> Here is some code mixing bitfields and longs in an union.
> Any comments on the validity and portability of this program ?


> union msg_t {
> struct elem {
> unsigned long foo: 16;
> unsigned long bar: 12;
> unsigned long type: 4;
> unsigned long length: 32;
> } elem;
> unsigned long data[2];
> } ;


> union msg_t msgh;
>
> msgh.elem.bar = 0x2;
> msgh.elem.foo = 0x3;
> msgh.elem.length = 0x100;
>
> printf("%08x\n", msgh.data[0]);
> printf("%08x\n", msgh.data[1]);


Yes. This is not portable ISO C. Assigning a value to any member of a
union makes all other members take unspecified (maybe even undefined; I
can't remember) values. One reason for this is that you don't know how
your bit fields are arranged inside their parent members.

Richard

gert.vierman@gmail.com 01-05-2006 06:53 PM

Re: bitfields in union : defined behaviour ?
 

Richard Bos wrote:
> gert.vierman@gmail.com wrote:
>
> > Here is some code mixing bitfields and longs in an union.
> > Any comments on the validity and portability of this program ?

>
> > union msg_t {
> > struct elem {
> > unsigned long foo: 16;
> > unsigned long bar: 12;
> > unsigned long type: 4;
> > unsigned long length: 32;
> > } elem;
> > unsigned long data[2];
> > } ;

>
> > union msg_t msgh;
> >
> > msgh.elem.bar = 0x2;
> > msgh.elem.foo = 0x3;
> > msgh.elem.length = 0x100;
> >
> > printf("%08x\n", msgh.data[0]);
> > printf("%08x\n", msgh.data[1]);

>
> Yes. This is not portable ISO C. Assigning a value to any member of a
> union makes all other members take unspecified (maybe even undefined; I
> can't remember) values. One reason for this is that you don't know how
> your bit fields are arranged inside their parent members.


Thank you, that is what I already expected.


Keith Thompson 01-05-2006 07:21 PM

Re: bitfields in union : defined behaviour ?
 
gert.vierman@gmail.com writes:
> Here is some code mixing bitfields and longs in an union.
> Any comments on the validity and portability of this program ?
> Thank you very much.
>
> #include <stdio.h>
>
> union msg_t {
>
> struct elem {
> unsigned long foo: 16;
> unsigned long bar: 12;
> unsigned long type: 4;
> unsigned long length: 32;
> } elem;
>
> unsigned long data[2];
>
> } ;
>
> int main(int argc, char **argv)
> {
> union msg_t msgh;
>
> msgh.elem.bar = 0x2;
> msgh.elem.foo = 0x3;
> msgh.elem.length = 0x100;
>
> printf("%08x\n", msgh.data[0]);
> printf("%08x\n", msgh.data[1]);
>
> return 0;
> }


Apart from the problems of accessing one member of a union after
storing a value in another member, the only portable types for
bitfields are int, unsigned int, signed int, and (in C99) _Bool.
Implementations may support other types as an extension.

Any bit fields larger than 16 bits are non-portable (since int is only
required to be 16 or more bits).

--
Keith Thompson (The_Other_Keith) kst-u@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.

dwks 01-08-2006 10:23 AM

Re: bitfields in union : defined behaviour ?
 
And you shouldn't make a bit field 8 bits or 16 or something -- in
those cases you can just use a char or something.


William J. Leary Jr. 01-09-2006 12:37 PM

Re: bitfields in union : defined behaviour ?
 
"dwks" <kingwilliams@primus.ca> wrote in message
news:1136672531.555318.222500@z14g2000cwz.googlegr oups.com...
> And you shouldn't make a bit field 8 bits or 16 or something -- in
> those cases you can just use a char or something.


I've used :8 to guarantee eight bits.

This was back in pre-ANSI days, with a program running on two platforms, one of
which had nine bit characters. I think I did it to save a lot of masking
operations, which were making the code hard to read. And which someone would
always forget at least one of when adding a new feature.

- Bill



Keith Thompson 01-09-2006 09:06 PM

Re: bitfields in union : defined behaviour ?
 
"dwks" <kingwilliams@primus.ca> writes:
> And you shouldn't make a bit field 8 bits or 16 or something -- in
> those cases you can just use a char or something.


Please read <http://cfaj.freeshell.org/google/> and follow its advice.

There's no guarantee that a char is 8 bits. There's no guarantee that
8-bit and 16-bit types even exists (I've used a system with no
predefined 16-bit integer type). The only guarantees are:

char >=8
short >=16
int >=16
long >=32
long long >=64 (C99 only)
char <= short <= int <= long <= long long

(I'm using a shorthand notation that should be clear enough, but
doesn't correspond to anything you'd see in a C expression.)

--
Keith Thompson (The_Other_Keith) kst-u@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.


All times are GMT. The time now is 02:14 AM.

Powered by vBulletin®. Copyright ©2000 - 2014, vBulletin Solutions, Inc.
SEO by vBSEO ©2010, Crawlability, Inc.