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