首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >static_cast能在位字段中工作吗?

static_cast能在位字段中工作吗?
EN

Stack Overflow用户
提问于 2017-12-08 10:03:48
回答 1查看 799关注 0票数 0

嗨,静态铸造为位域工作吗?因为这里我已经创建了一个32位长数据的位字段,我正在尝试将它转换为u32。

代码语言:javascript
复制
void CO2_SpiDriver::CreateBuffer() {
    //#[ operation CreateBuffer()
    typedef struct scr_t
     {
         union {
            u32 data;
             struct {
                 u8 CRC : 4; 
                 u16 Datatosend : 16;
                 u8 DataLengthCode : 2;
                 u8 AddressReg : 4;
                 u8 ReadandWrite : 1;
                 u8 InstrucCode : 3;
                 u8 ExtChipId : 2;
             };
         };
     } scr_t;  

     //set of data bits
     scr_t se;
     se.CRC = 0x00;   //CRC BITS 0 to 3
     se.Datatosend = 0x0000000000000000;  //Data bits 19 to 4
     se.DataLengthCode = 0x00; //DLC bits 21 and 20
     se.AddressReg = 0x00;     // SMP580 registers to access 25-22
     se.ReadandWrite = 0x01;  //Read|Write Reg 26
     se.InstrucCode = 0x5;    //InstrCode 29-27
     se.ExtChipId = 0x2;      //ExtChipId 31-30       

     static_cast<u32>(se)

但是在这里,我得到了一个错误,scr_t不能被抛给u32。有人能给我一些建议吗?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2017-12-08 10:08:36

在C++中,任何时候只有一个联合字段是活动的。重新解释内存布局的唯一可移植方法是使用std::memcpy

代码语言:javascript
复制
struct bf {
    u8 CRC : 4; 
    u16 Datatosend : 16;
    u8 DataLengthCode : 2;
    u8 AddressReg : 4;
    u8 ReadandWrite : 1;
    u8 InstrucCode : 3;
    u8 ExtChipId : 2;
};

bf se;
se.CRC = 0x00;   //CRC BITS 0 to 3
se.Datatosend = 0x0000000000000000;  //Data bits 19 to 4
se.DataLengthCode = 0x00; //DLC bits 21 and 20
se.AddressReg = 0x00;     // SMP580 registers to access 25-22
se.ReadandWrite = 0x01;  //Read|Write Reg 26
se.InstrucCode = 0x5;    //InstrCode 29-27
se.ExtChipId = 0x2;      //ExtChipId 31-30  

u32 se_as_u32;
static_assert(sizeof(se_as_u32) <= sizeof(se), "UB detector"); // avoid reading buffer overflow (see explanation below)
std::memcpy(&se_as_u32, &se, sizeof(se_as_u32));

注意:我增加了一行

代码语言:javascript
复制
static_assert(sizeof(se_as_u32) <= sizeof(se), "UB detector");

为了保护se在其“边界”之外被读取:

代码语言:javascript
复制
std::memcpy(&se_as_u32, &se, sizeof(se_as_u32));

它从sizeof(u32)中读取se字节(可能有4个字节)。在se小于4字节的情况下,memcpy会读取“of of it",这是一种缓冲区溢出,导致未定义的行为(这很糟糕)。在不尊重不平等的情况下(sizeof(se_as_u32) > sizeof(se)),将调用一个仁慈的abort(),程序会立即崩溃,而不是可能工作一段时间,并有一天破坏生产。

票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/47711930

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档