Argonne National Laboratory

Experimental Physics and
Industrial Control System

2002  2003  2004  2005  <20062007  2008  2009  2010  2011  2012  2013  2014  2015  2016  2017  2018  2019  2020  Index 2002  2003  2004  2005  <20062007  2008  2009  2010  2011  2012  2013  2014  2015  2016  2017  2018  2019  2020 
<== Date ==> <== Thread ==>

Subject: C strict aliasing rules
From: Eric Norum <norume@aps.anl.gov>
To: Core talk list <core-talk@aps.anl.gov>
Date: Wed, 22 Nov 2006 13:39:42 -0600
A discussion has been taking place on the RTEMS lists about the new strict aliasing rules in C. To illustrate the problem, consider the following small piece of code (provided by Till Straumann):

static inline void
writethree(int *p)
{
    short *palias = (short *)p;
   *palias = 3;
}

int
testalias()
{
    int value = 12345678;
    writethree(&value);
    return value;
}

One might expect that the value returned from testalias() would be 12345678 with either its most-significant 16 bits or least- significant 16 bits set to 3 (on most architectures).
....
One would be wrong, though.

Here's what gcc-4.1.1 produces for this example. I chose m68k assembly language to illustrate the problem, but the effect is the same for all architectures.

norume@gnarly 382> m68k-rtems4.7-gcc -O4 -S -Wall a.c
cnorume@gnarly 383> cat a.s
#NO_APP
        .file   "a.c"
        .text
        .align  2
        .globl  testalias
        .type   testalias, @function
testalias:
        link.w %fp,#-4
        move.l #12345678,%d0
        unlk %fp
        rts
        .size   testalias, .-testalias
        .ident  "GCC: (GNU) 4.1.1"

Notice that there are no warnings produced by the compiler.
Notice that the value returned is 12345678.
And the compiler is completely correct in doing this.  (!!!)

The 'strict aliasing' rules in C say that pointers to different types can be assumed to point to non-overlapping memory. Thus the compiler 'knows' that p and palias *must* point to non-overlapping space even though palias is a copy of p. So, the compiler knows that the location to which p is pointing is not being modified and thus optimizes away the effects of writethree().

I'm pretty sure that EPICS is going to break horribly if such strict aliasing rules are followed by the compiler. I propose that we add - fno-strict-aliasing to all gcc invocations and the equivalent to all other compiler invocations.

FWIW here's what's produced when this option is provided:
norume@gnarly 386> m68k-rtems4.7-gcc -fno-strict-aliasing -O4 -S a.c
norume@gnarly 387> cat a.s
#NO_APP
        .file   "a.c"
        .text
        .align  2
        .globl  testalias
        .type   testalias, @function
testalias:
        link.w %fp,#-4
        move.l %fp,%a0
        move.l #12345678,-(%a0)
        move.w #3,(%a0)
        move.l -4(%fp),%d0
        unlk %fp
        rts
        .size   testalias, .-testalias
        .ident  "GCC: (GNU) 4.1.1"

The writethree() has taken effect now.
--
Eric Norum <norume@aps.anl.gov>
Advanced Photon Source
Argonne National Laboratory
(630) 252-4793



Replies:
Re: C strict aliasing rules Andrew Johnson

Navigate by Date:
Prev: RE: building Posix for win32-x86? Jeff Hill
Next: Re: C strict aliasing rules Andrew Johnson
Index: 2002  2003  2004  2005  <20062007  2008  2009  2010  2011  2012  2013  2014  2015  2016  2017  2018  2019  2020 
Navigate by Thread:
Prev: RE: building Posix for win32-x86? Jeff Hill
Next: Re: C strict aliasing rules Andrew Johnson
Index: 2002  2003  2004  2005  <20062007  2008  2009  2010  2011  2012  2013  2014  2015  2016  2017  2018  2019  2020 
ANJ, 02 Feb 2012 Valid HTML 4.01! · Home · News · About · Base · Modules · Extensions · Distributions · Download ·
· Search · EPICS V4 · IRMIS · Talk · Bugs · Documents · Links · Licensing ·