Can this be done with "Union"

Discussion in 'C Programming' started by benn686@hotmail.com, Dec 7, 2007.

  1. Guest

    Id like to group 16 booleans into a u16 such that I can either set all
    16 variables at once with just a single u16 assigment, or I can
    individually change a bit by setting that boolean manually. Either
    way, the same 16 bits is occupied in memory.

    Something like...

    typedef struct
    {
    bool bSetLed15;
    bool bSetLed15;
    bool bSetLed14;
    bool bSetLed13;
    bool bSetLed12;
    bool bSetLed11;
    bool bSetLed10;
    bool bSetLed09;
    bool bSetLed08;
    bool bSetLed07;
    bool bSetLed06;
    bool bSetLed05;
    bool bSetLed04;
    bool bSetLed03;
    bool bSetLed02;
    bool bSetLed01;
    bool bSetLed00;
    } sLEDS;

    typedef struct
    {
    union
    {
    alt_u16 uAllLeds;
    sLEDS sSetSingleLed;
    } uSelection;

    } CONTROL;

    The problem is when I set the 16 bit variable, uAllLeds, the
    individual bits in the sLEDs structure (sSetSingleLed) arent set
    correctly. For example, ideally uAllLeds = 0x0300; would also set
    bSetLed09 = 1 and bSetLed08 = 1, with all other values to 0.

    Alternatively, if all leds are 0, and I set bSetLed15 = 1, I would
    like uAllLeds to automatically change to 0x8000.

    Is what Im trying to do possible using Union?
     
    , Dec 7, 2007
    #1
    1. Advertising

  2. Dave Hansen Guest

    On Dec 7, 5:17 pm, wrote:
    > Id like to group 16 booleans into a u16 such that I can either set all
    > 16 variables at once with just a single u16 assigment, or I can
    > individually change a bit by setting that boolean manually. Either
    > way, the same 16 bits is occupied in memory.
    >
    > Something like...
    >
    > typedef struct
    > {
    > bool bSetLed15;


    What's a "bool"?

    [...]
    >
    > } sLEDS;
    >
    > typedef struct
    > {
    > union
    > {
    > alt_u16 uAllLeds;


    What's a "alt_u16"?

    > sLEDS sSetSingleLed;
    > } uSelection;
    >
    > } CONTROL;
    >
    > The problem is when I set the 16 bit variable, uAllLeds, the
    > individual bits in the sLEDs structure (sSetSingleLed) arent set
    > correctly. For example, ideally uAllLeds = 0x0300; would also set
    > bSetLed09 = 1 and bSetLed08 = 1, with all other values to 0.
    >
    > Alternatively, if all leds are 0, and I set bSetLed15 = 1, I would
    > like uAllLeds to automatically change to 0x8000.
    >
    > Is what Im trying to do possible using Union?


    Yes, but not the way you are doing it.

    Try something like

    struct bits_16
    {
    unsigned bit1: 1;
    unsigned bit2: 1;
    unsigned bit3: 1;
    /*etc, until...*/
    unsigned bit16: 1;
    };

    union bits_word
    {
    uint16_t word;
    struct bits_16 bits;
    } var;

    var.word = 0;
    var.bits.bit5 = 1;
    printf ("Bit 5 is %x\n", var.word);

    Note that with the above scheme bit1 might not be the LSB -- That's up
    to the implementation. The bit order is allowed to change even
    between compiler versions...

    Regards,

    -=Dave
     
    Dave Hansen, Dec 8, 2007
    #2
    1. Advertising

  3. Ben Pfaff Guest

    Dave Hansen <> writes:

    > Try something like
    >
    > struct bits_16
    > {
    > unsigned bit1: 1;
    > unsigned bit2: 1;
    > unsigned bit3: 1;
    > /*etc, until...*/
    > unsigned bit16: 1;
    > };
    >
    > union bits_word
    > {
    > uint16_t word;
    > struct bits_16 bits;
    > } var;


    This might work, but it's not guaranteed. Besides bit-order
    issues, there's the problem that a union is only allowed to have
    one active member at the time. The compiler is allowed to
    optimize based on that assumption, so what happens might not be
    what the programmer expects.
    --
    A competent C programmer knows how to write C programs correctly,
    a C expert knows enough to argue with Dan Pop, and a C expert
    expert knows not to bother.
     
    Ben Pfaff, Dec 8, 2007
    #3
  4. Guest

    On Dec 7, 4:44 pm, Ben Pfaff <> wrote:
    > Dave Hansen <> writes:
    > > Try something like

    >
    > > struct bits_16
    > > {
    > > unsigned bit1: 1;
    > > unsigned bit2: 1;
    > > unsigned bit3: 1;
    > > /*etc, until...*/
    > > unsigned bit16: 1;
    > > };

    >
    > > union bits_word
    > > {
    > > uint16_t word;
    > > struct bits_16 bits;
    > > } var;

    >
    > This might work, but it's not guaranteed. Besides bit-order
    > issues, there's the problem that a union is only allowed to have
    > one active member at the time. The compiler is allowed to
    > optimize based on that assumption, so what happens might not be
    > what the programmer expects.
    > --
    > A competent C programmer knows how to write C programs correctly,
    > a C expert knows enough to argue with Dan Pop, and a C expert
    > expert knows not to bother.- Hide quoted text -
    >
    > - Show quoted text -



    The bit order couuld always be massaged, but it sounds like I may be
    outta luck...
    my compiler doesnt even support the "unsigned bit1: 1;" syntax!

    It doesnt like to see a declaration with a ":".. is that a new ansi c
    addition?

    If not by union, how is this kind of thing normally done?
     
    , Dec 8, 2007
    #4
  5. Ben Pfaff Guest

    writes:

    > If not by union, how is this kind of thing normally done?


    uint16_t foo;
    foo = 0x1234; /* Set the whole thing */
    foo |= 1u << 8; /* Set bit 8. */
    foo &= ~(1u << 3); /* Unset bit 3. */
    --
    "I don't have C&V for that handy, but I've got Dan Pop."
    --E. Gibbons
     
    Ben Pfaff, Dec 8, 2007
    #5
  6. Jack Klein Guest

    On Fri, 7 Dec 2007 17:01:47 -0800 (PST), wrote in
    comp.lang.c:

    > On Dec 7, 4:44 pm, Ben Pfaff <> wrote:
    > > Dave Hansen <> writes:
    > > > Try something like

    > >
    > > > struct bits_16
    > > > {
    > > > unsigned bit1: 1;
    > > > unsigned bit2: 1;
    > > > unsigned bit3: 1;
    > > > /*etc, until...*/
    > > > unsigned bit16: 1;
    > > > };

    > >
    > > > union bits_word
    > > > {
    > > > uint16_t word;
    > > > struct bits_16 bits;
    > > > } var;

    > >
    > > This might work, but it's not guaranteed. Besides bit-order
    > > issues, there's the problem that a union is only allowed to have
    > > one active member at the time. The compiler is allowed to
    > > optimize based on that assumption, so what happens might not be
    > > what the programmer expects.
    > > --
    > > A competent C programmer knows how to write C programs correctly,
    > > a C expert knows enough to argue with Dan Pop, and a C expert
    > > expert knows not to bother.- Hide quoted text -

    >
    > The bit order couuld always be massaged, but it sounds like I may be
    > outta luck...
    > my compiler doesnt even support the "unsigned bit1: 1;" syntax!


    I am absolutely sure that you are wrong about that. Any C or C++
    compiler for the past quarter century or so will accept that syntax.

    Almost certainly, you have not written the source code correctly. Post
    the smallest example you can write and compile to generate an error.

    > It doesnt like to see a declaration with a ":".. is that a new ansi c
    > addition?


    No, as I said above, this has been part of C for at least 25 years,
    and part of C++ for as long as it has existed.

    > If not by union, how is this kind of thing normally done?


    Post your code.

    --
    Jack Klein
    Home: http://JK-Technology.Com
    FAQs for
    comp.lang.c http://c-faq.com/
    comp.lang.c++ http://www.parashift.com/c -faq-lite/
    alt.comp.lang.learn.c-c++
    http://www.club.cc.cmu.edu/~ajo/docs/FAQ-acllc.html
     
    Jack Klein, Dec 8, 2007
    #6
  7. writes:
    [...]
    > The bit order couuld always be massaged, but it sounds like I may be
    > outta luck...
    > my compiler doesnt even support the "unsigned bit1: 1;" syntax!
    >
    > It doesnt like to see a declaration with a ":".. is that a new ansi c
    > addition?


    It's unlikely that your compiler doesn't support that syntax. Bit
    fields have been part of the language since before the first C
    standard.

    Try compiling the following:

    struct eight_bits {
    unsigned bit0: 1;
    unsigned bit1: 1;
    unsigned bit2: 1;
    unsigned bit3: 1;
    unsigned bit4: 1;
    unsigned bit5: 1;
    unsigned bit6: 1;
    unsigned bit7: 1;
    };

    Write just that declaration in a something.c file and try compiling
    it. If your compiler doesn't accept it, it's not a conforming C
    compiler. If it does, then there must have been some other error in
    your program.

    --
    Keith Thompson (The_Other_Keith) <>
    Looking for software development work in the San Diego area.
    "We must do something. This is something. Therefore, we must do this."
    -- Antony Jay and Jonathan Lynn, "Yes Minister"
     
    Keith Thompson, Dec 8, 2007
    #7
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Matt Garman
    Replies:
    1
    Views:
    669
    Matt Garman
    Apr 25, 2004
  2. Peter Dunker

    union in struct without union name

    Peter Dunker, Apr 26, 2004, in forum: C Programming
    Replies:
    2
    Views:
    875
    Chris Torek
    Apr 26, 2004
  3. João Gomes
    Replies:
    4
    Views:
    294
    fnegroni
    Feb 8, 2008
  4. Paul D. Fox

    I guess this can't be done can it ?

    Paul D. Fox, Jul 1, 2005, in forum: ASP .Net Web Controls
    Replies:
    2
    Views:
    132
    Steve Walker
    Jul 2, 2005
  5. Zhidian Du
    Replies:
    0
    Views:
    158
    Zhidian Du
    Feb 21, 2004
Loading...

Share This Page