title: C/C++ interop between _Complex and std::complex
body: <p>I have some C DSP libraries which use <code>complex [T]</code> types for complex numbers.  I want to call these from a C++ application which uses <code>std::complex&lt;T&gt;</code>.</p>
  
  <p>After reading <a href="https://stackoverflow.com/a/10540346/1156377">this SO answer</a> and <a href="https://stackoverflow.com/a/25348164/1156377">this one</a>, and §26.4 of <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n4296.pdf" rel="nofollow noreferrer">N4296</a>, I tried an experiment:</p>
  
  <pre><code>extern "C" {
  #include &lt;complex.h&gt;
  // Using _Complex or __complex__ since C's "complex" type doesn't exist in C++
  void cfunc(_Complex float x);
  }
  #include &lt;complex&gt;
  
  void test()
  {
          std::complex&lt;float&gt; z;
          cfunc(reinterpret_cast&lt;float[2]&gt;(z));
  }
  </code></pre>
  
  <p>And tried to compile it with <code>CXXFLAGS="-std=c++11"</code>.  I got the following from GCC 6.3.1:</p>
  
  <pre><code>error: invalid cast from type ‘std::complex&lt;float&gt;’ to type ‘float [2]’
    cfunc(reinterpret_cast&lt;float[2]&gt;(z));
  </code></pre>
  
  <p>Is this a compiler bug or am I misunderstanding something?  How would one use C functions which take <code>complex [T]</code> arguments, given C++ code using <code>std::complex&lt;T&gt;</code> types?  Currently, I use a dirty hack to work around this issue but I'd prefer a clean way.</p>
  
  <p>I tried compiling with <code>-std=c++14</code> just in case this feature had missed C++11 somehow (despite posts quoting it from the C++11 standard) but I get the same result.</p>
  
  <hr>
  
  <blockquote>
    <p>26.4 Complex numbers [complex.numbers]</p>
    
    <ol>
    <li><p>The header <code>&lt;complex&gt;</code> defines a class template, and numerous functions for representing and manipulating
    complex numbers.</p></li>
    <li><p>The effect of instantiating the template complex for any type other than float, double, or long double
    is unspecified. The specializations <code>complex&lt;float&gt;</code>, <code>complex&lt;double&gt;</code>, and <code>complex&lt;long double&gt;</code> are
    literal types (3.9).</p></li>
    <li><p>If the result of a function is not mathematically defined or not in the range of representable values for its
    type, the behavior is undefined.</p></li>
    <li><p>If z is an lvalue expression of type cv <code>std::complex&lt;T&gt;</code> then:</p>
    
    <p>4.1. the expression <code>reinterpret_cast&lt;cv T(&amp;)[2]&gt;(z)</code> shall be well-formed,</p>
    
    <p>4.2. <code>reinterpret_cast&lt;cv T(&amp;)[2]&gt;(z)[0]</code> shall designate the real part of z, and</p>
    
    <p>4.3. <code>reinterpret_cast&lt;cv T(&amp;)[2]&gt;(z)[1]</code> shall designate the imaginary part of z.</p></li>
    </ol>
  </blockquote>