bitfields in union : defined behaviour ?

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • gert.vierman@gmail.com

    #1

    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.lengt h = 0x100;

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

    return 0;
    }

  • gert.vierman@gmail.com

    #2
    Re: bitfields in union : defined behaviour ?


    gert.vierman@gm ail.com wrote:[color=blue]
    > 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.lengt h = 0x100;
    >
    > printf("%08x\n" , msgh.data[0]);
    > printf("%08x\n" , msgh.data[1]);
    >
    > return 0;
    > }[/color]

    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 ?

    Comment

    • Richard Bos

      #3
      Re: bitfields in union : defined behaviour ?

      gert.vierman@gm ail.com wrote:
      [color=blue]
      > Here is some code mixing bitfields and longs in an union.
      > Any comments on the validity and portability of this program ?[/color]
      [color=blue]
      > 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];
      > } ;[/color]
      [color=blue]
      > union msg_t msgh;
      >
      > msgh.elem.bar = 0x2;
      > msgh.elem.foo = 0x3;
      > msgh.elem.lengt h = 0x100;
      >
      > printf("%08x\n" , msgh.data[0]);
      > printf("%08x\n" , msgh.data[1]);[/color]

      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

      Comment

      • gert.vierman@gmail.com

        #4
        Re: bitfields in union : defined behaviour ?


        Richard Bos wrote:[color=blue]
        > gert.vierman@gm ail.com wrote:
        >[color=green]
        > > Here is some code mixing bitfields and longs in an union.
        > > Any comments on the validity and portability of this program ?[/color]
        >[color=green]
        > > 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];
        > > } ;[/color]
        >[color=green]
        > > union msg_t msgh;
        > >
        > > msgh.elem.bar = 0x2;
        > > msgh.elem.foo = 0x3;
        > > msgh.elem.lengt h = 0x100;
        > >
        > > printf("%08x\n" , msgh.data[0]);
        > > printf("%08x\n" , msgh.data[1]);[/color]
        >
        > 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.[/color]

        Thank you, that is what I already expected.

        Comment

        • Keith Thompson

          #5
          Re: bitfields in union : defined behaviour ?

          gert.vierman@gm ail.com writes:[color=blue]
          > 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.lengt h = 0x100;
          >
          > printf("%08x\n" , msgh.data[0]);
          > printf("%08x\n" , msgh.data[1]);
          >
          > return 0;
          > }[/color]

          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_Keit h) 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.

          Comment

          • dwks

            #6
            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.

            Comment

            • William J. Leary Jr.

              #7
              Re: bitfields in union : defined behaviour ?

              "dwks" <kingwilliams@p rimus.ca> wrote in message
              news:1136672531 .555318.222500@ z14g2000cwz.goo glegroups.com.. .[color=blue]
              > 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.[/color]

              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


              Comment

              • Keith Thompson

                #8
                Re: bitfields in union : defined behaviour ?

                "dwks" <kingwilliams@p rimus.ca> writes:[color=blue]
                > 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.[/color]

                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_Keit h) 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.

                Comment

                Working...