title: How to cast sockaddr_storage and avoid breaking strict-aliasing rules
body: <p>I'm using Beej's Guide to Networking and came across an aliasing issue.  He proposes a function to return either the IPv4 or IPv6 address of a particular struct:</p>
  
  <pre><code>1  void *get_in_addr( struct sockaddr *sa )
  2  {
  3      if (sa-&gt;sa_family == AF_INET)
  4        return &amp;(((struct sockaddr_in*)sa)-&gt;sin_addr);
  5      else
  6        return &amp;(((struct sockaddr_in6*)sa)-&gt;sin6_addr);
  7  }
  </code></pre>
  
  <p>This causes GCC to spit out a strict-aliasing error for <strong>sa</strong> on line 3.  As I understand it, it is because I call this function like so:</p>
  
  <pre><code>struct sockaddr_storage their_addr;
  ...
  inet_ntop(their_addr.ss_family,
            get_in_addr((struct sockaddr *)&amp;their_addr),
            connection_name,
            sizeof connection_name);
  </code></pre>
  
  <p>I'm guessing the aliasing has to do with the fact that the <code>their_addr</code> variable is of type <code>sockaddr_storage</code> and another pointer of a differing type points to the same memory.</p>
  
  <p>Is the best way to get around this sticking <code>sockaddr_storage</code>, <code>sockaddr_in</code>, and <code>sockaddr_in6</code> into a union?  It seems like this should be well worn territory in networking, I just can't find any good examples with best practices.</p>
  
  <p>Also, if anyone can explain exactly where the aliasing issue takes place, I'd much appreciate it.</p>