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 <[email protected]>
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
<2006>
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
- 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
<2006>
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
|