title: C++ struct mapped onto peripheral registers
body: <p>Let's say I have following code in C++ running on a <a href="https://www.xilinx.com/support/documentation/data_sheets/ds190-Zynq-7000-Overview.pdf" rel="nofollow noreferrer">Zynq-7000 SoC</a></p>
  <pre><code>  struct ControlReg
    {
      uint32_t reset_bit : 1;
    };
  
    struct ConfigReg
    {
      uint32_t even_channel_value : 16;
      uint32_t odd_channel_value : 16;
    };
  
    struct PeripheralRegs
    {
      volatile ControlReg control_reg;
      volatile uint32_t status_reg_01[2];
      volatile uint32_t status_reg_02[2];
      volatile ConfigReg config_reg_01[8];
      volatile ConfigReg config_reg_02[8];
      volatile uint32_t status_reg_03[2];
    };
  
    PeripheralRegs *regs;
    regs = new (reinterpret_cast&lt;void *&gt;(0x43C20000)) PeripheralRegs;
  
    uint16_t value = 6573;
  
    regs-&gt;config_reg_01[0].odd_channel_value = value;
    regs-&gt;config_reg_01[0].even_channel_value = value;
  </code></pre>
  <p>I have stepped through this code in debugger and I have found that the <code>config_reg_01[0]</code>
  contains all zeros despite the attempt to write the <code>6573</code> value into it. Can anybody tell me why this behavior occurs? It is strange for me that in case I write some value into the <code>status_reg_01[0]</code> I see this value at the appropriate address in the &quot;memory monitor&quot; in the debugger.</p>
  <p><strong>EDIT</strong>:</p>
  <p>I have partially found the reason why this behavior occurs. It is somehow related to the code optimization. This conclusion is based on the observation that the problem vanished in case I switched the code optimization level from O2 to O0 in the ARM v7 g++ compiler settings. Second observation which I have is that in case I use code optimization level O2 and made following modifications:</p>
  <pre><code>  struct ControlReg
    {
      volatile uint32_t reset_bit : 1;
    };
  
    struct ConfigReg
    {
      volatile uint32_t even_channel_value : 16;
      volatile uint32_t odd_channel_value : 16;
    };
  </code></pre>
  <p>the same correct behavior occurs as in the case with optimization level O0.
  Can anybody explain to me why the <code>volatile</code> keyword applied onto the bitfields items has such huge impact in relation to the code optimization.</p>