0

I have an AVR program which stores a set (usually less than 8) bit flags in a static status variable (which is contained inside a struct holding various other state fields of the module).

if it more or less efficient to do it like this:

#define STATUS_ENABLED 0x01

struct DeviceState {
    uint8_t status;
}

static struct DeviceState myState;

//and somewhere in the program...
myState.status |= STATUS_ENABLED;

Or do it with a packed bitfield:

struct DeviceState {
    uint8_t enabled : 1;
}

static struct DeviceState myState;

//and somewhere in the program...
myState.enabled = 1; // could use TRUE/FALSE if defined
Inductiveload
  • 6,094
  • 4
  • 29
  • 55

3 Answers3

3

With avr-gcc 4.3.3, it seems there is no difference in implementation:

#define STATUS_ENABLE

struct DeviceState {
    uint8_t status;
    uint8_t enabled : 1;
}

static struct DeviceState myState;

//and this code...
myState.status |= STATUS_ENABLED;
myState.enabled = 1;

produces the following assembly code:

    myState.status |= STATUS_ENABLE;
00003746  LDS R24,0x20B5            Load direct from data space 
00003748  ORI R24,0x01              Logical OR with immediate 
00003749  STS 0x20B5,R24            Store direct to data space 

    myState.enabled = TRUE;
0000374B  LDS R24,0x20B4            Load direct from data space 
0000374D  ORI R24,0x01              Logical OR with immediate 
0000374E  STS 0x20B4,R24            Store direct to data space 

So the same instructions (except for the address!).

Inductiveload
  • 6,094
  • 4
  • 29
  • 55
2

The bit field version is non-portable and the actual location of the bits is poorly defined. Apart from that, there should be no differences. Therefore, use the former version, since it is 100% portable.

Lundin
  • 195,001
  • 40
  • 254
  • 396
-2

The packed bitfield allows you to store additional variables in a 8 bit memory space, so it would be more memory efficient if you are going to add more variables to DeviceStatus.

umps
  • 1,119
  • 4
  • 15
  • 25