Can this be done with "Union"

B

benn686

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?
 
D

Dave Hansen

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
 
B

Ben Pfaff

Dave Hansen said:
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.
 
B

benn686

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?
 
B

Ben Pfaff

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. */
 
J

Jack Klein

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
 
K

Keith Thompson

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.
 

Ask a Question

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

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,744
Messages
2,569,484
Members
44,903
Latest member
orderPeak8CBDGummies

Latest Threads

Top