title: Providing a C API to your C++ library and strict aliasing
body: <p>A common pattern when providing a C API is to forward declare some opaque types in your public header which are passed to your API methods and then <code>reinterpret_cast</code> them into your defined C++ types once inside the translation unit (and therefore back in C++ land).</p>
  
  <h2>Using LLVM as an example:</h2>
  
  <p>In <a href="https://github.com/llvm-mirror/llvm/blob/master/include/llvm-c/Types.h#L54" rel="noreferrer">Types.h</a> this typedef is declared:</p>
  
  <pre><code>typedef struct LLVMOpaqueContext *LLVMContextRef;
  </code></pre>
  
  <p><code>LLVMOpaqueContext</code> is not referenced anywhere else in the project.</p>
  
  <p>In <a href="https://github.com/llvm-mirror/llvm/blob/master/include/llvm-c/Core.h#L389" rel="noreferrer">Core.h</a> the following method is declared:</p>
  
  <pre><code>LLVMContextRef LLVMContextCreate(void);
  </code></pre>
  
  <p>Which is defined in <a href="https://github.com/llvm-mirror/llvm/blob/master/lib/IR/Core.cpp#L79" rel="noreferrer">Core.cpp</a>:</p>
  
  <pre><code>LLVMContextRef LLVMContextCreate() {
    return wrap(new LLVMContext());
  }
  </code></pre>
  
  <p><code>wrap</code> (and <code>unwrap</code>) is defined by a macro in <a href="https://github.com/llvm-mirror/llvm/blob/master/include/llvm/Support/CBindingWrapping.h#L20" rel="noreferrer">CBindingWrapping.h</a>:</p>
  
  <pre><code>#define DEFINE_SIMPLE_CONVERSION_FUNCTIONS(ty, ref)     \
    inline ty *unwrap(ref P) {                            \
      return reinterpret_cast&lt;ty*&gt;(P);                    \
    }                                                     \
                                                          \
    inline ref wrap(const ty *P) {                        \
      return reinterpret_cast&lt;ref&gt;(const_cast&lt;ty*&gt;(P));   \
  }
  </code></pre>
  
  <p>And used in <a href="https://github.com/llvm-mirror/llvm/blob/master/include/llvm/IR/LLVMContext.h#L334" rel="noreferrer">LLVMContext.h</a>:</p>
  
  <pre><code>DEFINE_SIMPLE_CONVERSION_FUNCTIONS(LLVMContext, LLVMContextRef)
  </code></pre>
  
  <p>So we see that the C API basically takes a pointer to an <code>LLVMOpaqueContext</code> and casts it into an <code>llvm::LLVMContext</code> object to perform whatever method is called on it.</p>
  
  <p>My question is: isn't this in violation of the strict aliasing rules? If not, why not? And if so, how can this type of abstraction at the public interface boundary be acheived legally?</p>