加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > Windows > 正文

将uint32变量转换为位字段 – 未定义的行为?

发布时间:2020-12-14 02:27:05 所属栏目:Windows 来源:网络整理
导读:我有一个由微控制器制造商提供的寄存器定义,可以作为位字段处理.寄存器定义如下: #define SCU_WDTSCON0 (*( SCU_WDTSCON0_type *) 0xf00360f0u) 位字段定义如下所示: typedef volatile union {unsigned U;int I;struct { unsigned ENDINIT :1; // [0:0] En
我有一个由微控制器制造商提供的寄存器定义,可以作为位字段处理.寄存器定义如下:

#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.)

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读