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?
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.)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With