Source-Changes-D archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

Re: CVS commit: src/sys/arch/atari/stand/installboot



   Date: Mon, 24 Nov 2014 22:39:24 +0900
   From: Izumi Tsutsui <tsutsui%ceres.dti.ne.jp@localhost>

   I don't think it's worth because binaries have worked without changes.
   (if the compiler tries reorder optimization per strict-aliasing rule
    I guess wrong implementation will be warned at that time)

No -- GCC will only warn by default if it can prove you're violating
the strict-aliasing rules.  It may not warn if it merely makes a
decision on the basis of strict-aliasing rules.

For example, in

struct foo { int x; };
struct bar { int y; };

int
frob(struct foo *f, struct bar *b)
{

	f->x = 0;
	b->y = 1;
	return f->x;
}

GCC may (and in fact does) generate code for frob that always returns
0, because a struct foo is not allowed to alias a struct bar, so the
`b->y = 1' assignment can't change f->x.

This code does not itself violate strict-aliasing rules, but if you
call it with

	struct foo f;
	frob(&f, (struct bar *)&f);

then you have violated the rule, and you will get the `wrong' answer
(because this is undefined behaviour).  GCC may not warn about the
cast: if frob is in a different compilation unit, GCC may not know
that frob is going to dereference both pointers.

In the case of abcksum, if you have

uint8_t p[512];
...
*((uint16_t *)p + 255) = 0;
*((uint16_t *)p + 255) = abcksum(p);

GCC may choose to evaluate abcksum before the zero assignment, because
no uint16_t is allowed to alias a uint8_t, so the assignment of an
lvalue with type uint16_t can't change the value of abcksum(p).

The result would be the same as writing simply

uint8_t p[512];
...
*((uint16_t *)p + 255) = abcksum(p);

which is almost certainly not what you intend.


Home | Main Index | Thread Index | Old Index