[th/gcc4] apps fixing guide #2 - aliasing violations.
Grzegorz Konopko
kolodko1 w wp.pl
Pią, 5 Maj 2006, 16:36:49 CEST
Dnia czwartek, 4 maja 2006 22:34, Grzegorz Konopko napisał:
> Dnia czwartek, 4 maja 2006 20:22, Paweł Sikora napisał:
> > [3] OK.
> > tutaj nadal jest poprawnie, bo typ znakowy może się nakładać na inne
> > typy.
> >
> > bool tell_endian()
> > {
> > unsigned x = 1;
> > return *(char*)&x;
> > }
> >
> > jednak dobrą praktyką jest unikać rzutowania przez wskaźniki
> > i zapisać powyższy przykład z użyciem unii -> [4].
>
> W powyższym chodzi o przejrzystość kodu?
>
> ze 2 tygodnie temu naciąłem sie na podobny własny trick, uzywam takich duzo
> bo czasem trzeba.
> Ale nie rozumiem dlaczego właściwie tak to tłumaczą,
To było głupie pytanie. To przecież Ansi/ISO.
Cieakwy przykład wyciagnelem z jednego tutoriala do srodowiska
programistycznego.
/************************************************************************/
short f(short *sptr, long *lptr)
{
short x = *sptr;
*lptr = 0;
return *sptr + x;
}
short fail()
{
union
{
short s[2];
long l;
} u;
u.s[0] = 4711;
return f(&u.s[0], &u.l);
}
int main ()
{
printf("%d\n",fail());
return 0;
}
/************************************************************************/
i komentarz:
Because the *lptr = 0 assignment cannot affect the object sptr points to, the
optimizer will assume that *sptr in the return statement has the same value
as variable x was assigned at the beginning of the function. Hence, it is
possible to eliminate a memory access by returning x << 1 instead of *sptr +
x.
Co ciekawe na gcc zz Ac i gcc z th przy -O2 daje wynik 9422, przy wszystkich
innych nawet -O3 daje 4711. Nie wiem czemu przy -O3 daje 4711(?).
Dodam jeszcze jeden fragment do tego co napisane w podreczniku gcc wziete z
tego samego źródła:
short s;
unsigned short us;
long l;
unsigned long ul;
float f;
unsigned short *usptr;
char *cptr;
struct A
{
short s;
float f;
} a;
void test(float *fptr, long *lptr)
{
/* May affect: */
*lptr = 0; /* l, ul */
*fptr = 1.0; /* f, a */
*usptr = 4711; /* s, us, a */
*cptr = 17; /* s, us, l, ul, f, usptr, cptr, a */
}
Because an object shall only be accessed as its declared type (or a qualified
version of its declared type, or a signed/unsigned type corresponding to its
declared type) it is also assumed that the object that fptr points to will
not be affected by an assignment to the object that lptr points to.
Więcej informacji o liście dyskusyjnej pld-devel-pl