Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Cast a uint32 variable to a bit field - undefined behavior?

I have a register definition provided by the microcontroller manufacturer that can be handled as a bit field. The register is defined as follows:

#define SCU_WDTSCON0 (*( SCU_WDTSCON0_type *) 0xf00360f0u)

The bit field definition looks like this:

typedef volatile union {
unsigned U;
int I;
struct {
    unsigned    ENDINIT  :1;    // [0:0] End-of-Initialization Control Bit
    unsigned    LCK  :1;    // [1:1] Lock Bit to Control Access to WDTxCON0
    unsigned    HPW0     :2;    // [3:2] Hardware Password 0
    unsigned    HPW1     :4;    // [7:4] Hardware Password 1
    unsigned    PW   :8;    // [15:8] User-Definable Password Field for Access to WDTxCON0
    unsigned    REL  :16;   // [31:16] Reload Value for the WDT
  } B;
} SCU_WDTSCON0_type;

Instead of directly writing to the register, I want to use a uint32 buffer variable first, but still be able to edit it in the manner of the register bit field definition. This implementation seems to be working, as the address is just replaced with &buffer_variable:

volatile uint32 buffer_variable;
SCU_WDTSCON0_type register_buffer = (*( SCU_WDTSCON0_type *) &buffer_variable);

Could this lead to undefined behavior?

like image 940
Mentulatus Avatar asked Apr 07 '16 09:04

Mentulatus


1 Answers

Your buffer variable needs to be exactly the same type as one of the union members, in this case unsigned. In case the compiler treats uint32 and unsigned as different types, it will lead to undefined behavior (violates strict aliasing rule). Otherwise, if they are the same type, the code is fine.

(As a side note, most bugs related to strict aliasing violations are caused by the compiler's optimizer. In case of volatile variables, this is less of an issue, since the compiler isn't allowed to optimize them anyway. So in practice, I doubt you'll ever encounter any UB for this scenario, even though it could be UB in theory.)

like image 114
Lundin Avatar answered Oct 19 '22 16:10

Lundin