Strict-aliasing rules (gcc 4.4)

Alexander Bartolich alexander.bartolich at gmx.at
Thu Aug 20 22:57:06 UTC 2009


Julien ÉLIE wrote:
  > With gcc 4.4, there are lots of errors like:
> 
> rc.c:151: error: dereferencing pointer 's_local' does break 
> strict-aliasing rules
> rc.c:573: error: dereferencing pointer 'remote.59' does break 
> strict-aliasing rules
> ...
> 
> 
> -->  if( s_local->sa_family == AF_INET6 )
>     {
>       struct sockaddr_in6 *s_l6 = (struct sockaddr_in6 *)s_local;
>       struct sockaddr_in6 *s_d6 = (struct sockaddr_in6 *)s_distant;
> 
> 
> --> memcpy(&remotetable[i].Address, &remote, SA_LEN((struct sockaddr 
> *)&remote));
> 
> 
> What could we do for that?

I have no gcc 4.4 to test this. But my guess is that you have five options.

a) compile without optimization
b) use memcpy to copy from one variable to the other
c) declare pointers with __attribute__((may_alias))
d) declare pointers const (this may or may not shut up the compiler)
e) use a union instead of a type cast, e.g.
    union
    {
      struct sockaddr s;
      struct sockaddr_in s_l4;
      struct sockaddr_in6 s_l6;
    } u;
    This has the advantage that the non-aliasing properties of union are
    part of the language description, so no compiler specific magic is
    required.

> Why such calls are not fine?

With a non-aliased pointer the compiler can make assumptions about the
value of things, e.g. with

   s_local->sa_family = 0;
   family = s_local->sa_family;

it can assign a literal 0 to "family" without dereferencing the pointer.
On the other hand an aliased pointer has to be dereferenced every time, e.g.

   s_local->sa_family = 0;
   s_l6->sin6_family = 1;
   family = s_local->sa_family;

Ciao

     Alexander.



More information about the inn-workers mailing list