[Spread-users] type punning

Neil Conway neilc at samurai.com
Mon Sep 19 15:40:48 EDT 2005


Spread3 does not obey the strict aliasing rules mandated by the C
standard. This provokes the following warnings when compiling Spread
(with GCC 4.0.1):

% make
[...]
../spread-3.17.3.orig/events.c: In function ‘E_get_time’:
../spread-3.17.3.orig/events.c:138: warning: dereferencing type-punned
pointer will break strict-aliasing rules
../spread-3.17.3.orig/events.c: In function ‘E_delay’:
../spread-3.17.3.orig/events.c:336: warning: dereferencing type-punned
pointer will break strict-aliasing rules
../spread-3.17.3.orig/events.c: In function ‘E_handle_events’:
../spread-3.17.3.orig/events.c:637: warning: dereferencing type-punned
pointer will break strict-aliasing rules
../spread-3.17.3.orig/events.c:653: warning: dereferencing type-punned
pointer will break strict-aliasing rules
../spread-3.17.3.orig/data_link.c: In function ‘DL_send’:
../spread-3.17.3.orig/data_link.c:229: warning: dereferencing
type-punned pointer will break strict-aliasing rules
../spread-3.17.3.orig/sp.c: In function ‘recv_nointr_timeout’:
../spread-3.17.3.orig/sp.c:196: warning: dereferencing type-punned
pointer will break strict-aliasing rules
../spread-3.17.3.orig/sp.c: In function ‘connect_nointr_timeout’:
../spread-3.17.3.orig/sp.c:265: warning: dereferencing type-punned
pointer will break strict-aliasing rules

These are all caused by casting an sp_time * to a struct timeval *,
which is not legal under strict aliasing rules (you can't assume that
the compiler will lay out the fields of two distinct structures in the
same way).

The easiest way to fix this is to use the -fno-strict-aliasing gcc
option when it is available (at least when using GCC). Longer term, I
wonder if there is much value in keeping sp_time -- this problem would
be avoided by either defining sp_time as a typedef for struct timeval,
or just removing sp_time entirely (and exposing struct timeval as part
of the Spread client API). Either of these would break the client ABI,
although perhaps that is acceptable for Spread4.

You could also manually convert an sp_time into a struct timeval when
needed:

void foo(sp_time *time, ...)
{
    struct timeval tv;

    tv.tv_sec = time->sec;
    tv.tv_usec = time->usec;
    /* use `tv' as needed... */
    (void) gettimeofday(&tv, NULL);
}

although of course that's pretty ugly.

I'd be happy to submit a patch for configure.in to check for and use
-fno-strict-aliasing when available, but I'm curious as to how others
think this problem should be resolved in the long run.

-Neil






More information about the Spread-users mailing list