title: Why is std::launder required here?
body: <p>I was reading cppreference and in the example for <a href="https://en.cppreference.com/w/cpp/types/aligned_storage#:%7E:text=The%20type%20defined%20by%20std%3A%3Aaligned_storage%3C%3E%3A%3Atype%20can%20be%20used,for%20example%20on%20a%20cache%20or%20page%20boundary." rel="nofollow noreferrer">std::aligned_storage</a> is had this example of a vector/array class:</p>
  <pre><code>template&lt;class T, std::size_t N&gt;
  class static_vector
  {
      // properly aligned uninitialized storage for N T's
      typename std::aligned_storage&lt;sizeof(T), alignof(T)&gt;::type data[N];
      // IF you want to see possible implementation of aligned storage see link.
      // It's very simple and small, it's just a buffer
      
      std::size_t m_size = 0;
   
  public:
      // Create an object in aligned storage
      template&lt;typename ...Args&gt; void emplace_back(Args&amp;&amp;... args) 
      {
          if( m_size &gt;= N ) // possible error handling
              throw std::bad_alloc{};
   
          // construct value in memory of aligned storage
          // using inplace operator new
          new(&amp;data[m_size]) T(std::forward&lt;Args&gt;(args)...);
          ++m_size;
      }
   
      // Access an object in aligned storage
      const T&amp; operator[](std::size_t pos) const 
      {
          // note: needs std::launder as of C++17
          // WHY
          return *reinterpret_cast&lt;const T*&gt;(&amp;data[pos]);
      }
   
      // Delete objects from aligned storage
      ~static_vector() 
      {
          for(std::size_t pos = 0; pos &lt; m_size; ++pos) {
              // note: needs std::launder as of C++17
              // WHY?
              reinterpret_cast&lt;T*&gt;(&amp;data[pos])-&gt;~T();
          }
      }
  };
  </code></pre>
  <p>Essentially each bucket/area/address of memory where each element resides is a char buffer. At each element position that exists a placement new is done in that buffer of the T type. So that when returning the position of that buffer that char buffer can be cast to T* because a T was constructed there. Why is std::launder required from C++17 onwards? I have asked a bunch of questions about this and it seems agreed that:</p>
  <pre><code>alignas(alignof(float)) char buffer [sizeof(float)];
  new (buffer) float;// Construct a float at memory, float's lifetime begins
  float* pToFloat = buffer; // This is not a strict aliasing violation
  *pToFloat = 7; // Float is live here
  </code></pre>
  <p>This is not a strict aliasing violation apparently, it's completely fine. So therefore why is std::launder required here?</p>