title: bitwise casting uint32_t to float in C/C++
body: <p>I'm receiving a buffer from a network which was converted to an array of 32-bit words.  I have one word which is defined as an IEEE-754 float by my interface document. I need to extract this word from the buffer.  It's tough to cast from one type to another without invoking a conversion.  The bits are already adhere to the IEEE-754 float standard, I don't want to re-arrange any bits.</p>
  <p>My first try was to cast the address of the <code>uint32_t</code> to a <code>void*</code>, then convert the <code>void*</code> to a <code>float*</code>, then dereference as a <code>float</code>:</p>
  <pre><code>float ieee_float(uint32_t f)
  {
      return *((float*)((void*)(&amp;f)));
  }
  </code></pre>
  <blockquote>
  <p>error: dereferencing type-punned pointer will break strict-aliasing rules [-Werror=strict-aliasing]</p>
  </blockquote>
  <p>My second try was like this:</p>
  <pre><code>float ieee_float(uint32_t f)
  {
      union int_float{
          uint32_t i;
          float f;
      } tofloat;
  
      tofloat.i = f;
      return tofloat.f;
  }
  </code></pre>
  <p>However, word on the street is that unions are totally unsafe.  It's undefined behavior to read from the member of the union that wasn't most recently written.</p>
  <p>So I tried a more C++ approach:</p>
  <pre><code>float ieee_float(uint32_t f)
  {
    return *reinterpret_cast&lt;float*&gt;(&amp;f);
  }
  </code></pre>
  <blockquote>
  <p>error: dereferencing type-punned pointer will break strict-aliasing rules [-Werror=strict-aliasing]</p>
  </blockquote>
  <p>My next thought was &quot;screw it. Why am I dealing with pointers anyways?&quot; and just tried:</p>
  <pre><code>float ieee_float(uint32_t f)
  {
    return reinterpret_cast&lt;float&gt;(f);
  }
  </code></pre>
  <blockquote>
  <p>error: invalid cast from type ‘uint32_t {aka unsigned int}’ to type ‘float’</p>
  </blockquote>
  <p>Is there a way to do the conversion without triggering the warning/error?  I'm compiling with g++ using <code>-Wall -Werror</code>.  I'd prefer to not touch compiler settings.</p>
  <p>I tagged C because a c-solution is acceptable.</p>