2017-12-08 5 views
0

こんにちはビットフィールドの静的キャスト作業は?ここで私は32ビットのロングデータのビットフィールドを作成して、私はそれをu32にキャストしようとしています。ビットフィールドに対してstatic_castを使用できますか?

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にキャストできないというエラーが表示されます。誰でも提案をすることができます

+0

* correction * static_cast (se) –

+2

'static_cast'は_related_タイプでのみ動作します。 – user0042

+5

'se.data'はすでに' u32'です。 – tkausl

答えて

4

C++では、いつでもユニオンのフィールドの1つだけがアクティブになります。メモリレイアウトを再解釈する唯一のポータブルな方法はstd::memcpyを使用することです:

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)); 

注:私はその外読み取ることがseを保護するためにライン

static_assert(sizeof(se_as_u32) <= sizeof(se), "UB detector"); 

を追加しました「境界」:

std::memcpy(&se_as_u32, &se, sizeof(se_as_u32)); 

これはsizeof(u32)(おそらく4)バイト〜から。 seが4バイトよりも小さい場合、memcpyは "outside of it"と表示されますが、これは一種のバッファオーバーフローであり、未定義の動作になります(これは悪い)。 不等式が尊重されていない場合(sizeof(se_as_u32) > sizeof(se))、慈悲的なabort()が呼び出され、プログラムは一時的に働いていて、1日で生産を破棄するのではなく、即座にクラッシュします。

+0

"ポータブル"のように "ホーリーISO標準の保証のみを使用して、実際のコンパイラを無視するか、g ++でそれらをすべてコンパイルする"のように。 –

+1

@ Cheersandhth.-アルフあなたのポイントは何ですか? – YSC

+0

C++ 20では、新しい ''ヘッダの 'bit_cast'が' memcpy() 'の冗長さを避け、より多くのコンパイラ組み込み関数を利用するでしょう。 –

関連する問題