[PATCH 2] fix broken strict aliasing

Brandon Black blblack at gmail.com
Mon Feb 22 19:59:08 CET 2010

On Sun, Feb 21, 2010 at 3:39 AM, Marc Lehmann <schmorp at schmorp.de> wrote:
> On Sat, Feb 20, 2010 at 09:41:35AM -0600, Brandon Black <blblack at gmail.com> wrote:
>> I've seen this strict-aliasing issues with libev + gcc 4.4 as well.  I
> Facts please...

I wasn't asserting that there was an aliasing issue in libev.  I was
asserting that there is a strict aliasing warning with gcc + libev,
and I said I haven't fully investigated it to figure out what the
cause is.  So I agree, I still don't have facts.

The real issue here is that I apparently don't understand, precisely
and in-depth, exactly what the C standard says about aliasing, and
exactly what gcc says about the same, and whether they agree or not.
Apparently I'm not the only one, as evidenced not only by this thread,
but by Google searches turning up many similar threads on many other
mailing lists, as well as web pages that attempt to explain the issue,
and then other pages/threads calling those pages horse-shit.

I'd like to take a simple case here and break it down, if you don't mind:


blblack at xpc:~$ cat test.c

struct foo {
   int a;

struct bar {
   int a;

struct bar sbar;

int get_a(void) {
    return ((struct foo*)(&sbar))->a;

blblack at xpc:~$ gcc -std=c99 -O3 -Wall -c test.c
test.c: In function ‘get_a’:
test.c:13: warning: dereferencing type-punned pointer will break
strict-aliasing rules

blblack at xpc:~$ gcc -v
Using built-in specs.
Target: x86_64-linux-gnu
Configured with: ../src/configure -v --with-pkgversion='Ubuntu
--enable-languages=c,c++,fortran,objc,obj-c++ --prefix=/usr
--enable-shared --enable-multiarch --enable-linker-build-id
--with-system-zlib --libexecdir=/usr/lib --without-included-gettext
--enable-threads=posix --with-gxx-include-dir=/usr/include/c++/4.4
--program-suffix=-4.4 --enable-nls --enable-clocale=gnu
--enable-libstdcxx-debug --enable-objc-gc --disable-werror
--with-arch-32=i486 --with-tune=generic --enable-checking=release
--build=x86_64-linux-gnu --host=x86_64-linux-gnu
Thread model: posix
gcc version 4.4.1 (Ubuntu 4.4.1-4ubuntu9)


The code above is a simplified version of a line at the beginning of
evpipe_init() which generates the same warning.  The original line is

if (!ev_is_active (&pipe_w))

which after pre-processing is this:

if (!(0 + ((ev_watcher *)(void *)(&((loop)->pipe_w)))->active))

In the definition of "struct ev_loop", pipe_w is a member of type
"struct ev_io" (not a pointer, a direct sub-struct).  ev_io and
ev_watcher have a common first member, "int active".

Can someone who understands the relevant standards and whatever modern
gcc is doing with aliasing explain what the standards say about the
test case snippet above, and why gcc is (possibly erroneously?)
warning on it?

-- Brandon

More information about the libev mailing list