将 uint32 变量转换为位域 - 未定义的行为?
Cast a uint32 variable to a bit field - undefined behavior?
我有微控制器制造商提供的寄存器定义,可以作为位域处理。寄存器定义如下:
#define SCU_WDTSCON0 (*( SCU_WDTSCON0_type *) 0xf00360f0u)
位域定义如下所示:
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;
我不想直接写入寄存器,而是想先使用一个uint32缓冲区变量,但仍然可以按照寄存器位域定义的方式对其进行编辑。
此实现似乎有效,因为地址只是替换为 &buffer_variable:
volatile uint32 buffer_variable;
SCU_WDTSCON0_type register_buffer = (*( SCU_WDTSCON0_type *) &buffer_variable);
这会导致未定义的行为吗?
您的缓冲区变量需要与其中一个联合成员的类型完全相同,在本例中为 unsigned
。如果编译器将 uint32
和 unsigned
视为不同的类型,则会导致未定义的行为(违反严格的别名规则)。否则,如果它们是同一类型,代码就可以了。
(作为旁注,大多数与严格的别名违规相关的错误都是由编译器的优化器引起的。对于 volatile 变量,这不是一个问题,因为编译器无论如何都不允许优化它们。所以在实践中,我怀疑你会遇到这种情况的任何 UB,即使它在理论上可能是 UB。)
我有微控制器制造商提供的寄存器定义,可以作为位域处理。寄存器定义如下:
#define SCU_WDTSCON0 (*( SCU_WDTSCON0_type *) 0xf00360f0u)
位域定义如下所示:
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;
我不想直接写入寄存器,而是想先使用一个uint32缓冲区变量,但仍然可以按照寄存器位域定义的方式对其进行编辑。 此实现似乎有效,因为地址只是替换为 &buffer_variable:
volatile uint32 buffer_variable;
SCU_WDTSCON0_type register_buffer = (*( SCU_WDTSCON0_type *) &buffer_variable);
这会导致未定义的行为吗?
您的缓冲区变量需要与其中一个联合成员的类型完全相同,在本例中为 unsigned
。如果编译器将 uint32
和 unsigned
视为不同的类型,则会导致未定义的行为(违反严格的别名规则)。否则,如果它们是同一类型,代码就可以了。
(作为旁注,大多数与严格的别名违规相关的错误都是由编译器的优化器引起的。对于 volatile 变量,这不是一个问题,因为编译器无论如何都不允许优化它们。所以在实践中,我怀疑你会遇到这种情况的任何 UB,即使它在理论上可能是 UB。)