Fwd: Problem report: Struct aliasing problem causes Thread_Ready_Chain corruption in 4.6.99.3
Aaron J. Grier
aaron at frye.com
Wed Nov 22 23:27:18 UTC 2006
On Tue, Nov 21, 2006 at 12:21:40PM -0800, Till Straumann wrote:
> typedef union {
> int i;
> short s;
> } u2;
>
> int rtn3()
> {
> int rval = 3;
> u2 *pu = &rval;
> short *ps = (short*)pu;
> *ps = 0xdead;
> return rval;
> }
>
> Even though casting a int* into u2* is legal (u2 contains a int
> member) and u2* to short* is, too (u2 also contains a short member)
> gcc still optimizes *ps=0xdead away because it says: at the end of the
> day, ps must not be an alias of &rval and it knows that both point to
> the same address.
in the above example u2 is declared as a union between a short and an
int, and pu is declared as a pointer to a u2 union. however, no space
is declared for the data being held in the union, so the above appears
fishy.
don't you want something like this:
typedef union {
int *i;
short *s;
} u2;
int rtn3()
{
int rval = 3;
u2 pu;
short *ps;
pu.i = &rval;
ps = pu.s;
*ps = 0xdead;
return rval;
}
no casts necessary.
or if you are doing data overlays between int and short (and RTEMS
supercore objects)
typedef union {
int i;
short s;
} u4;
int rtn4()
{
int *rval;
short *ps;
u4 pu;
rval = &pu.i;
pu.i = 3;
ps = &pu.s;
*ps = 0xdead;
return *rval;
}
I almost guarantee that example isn't endian safe, but does illustrate
my point. casts? who needs 'em?
--
Aaron J. Grier | Frye Electronics, Tigard, OR | aaron at frye.com
More information about the users
mailing list