This is the mail archive of the
gcc-bugs@gcc.gnu.org
mailing list for the GCC project.
Re: 2.95 compiler bug with optimization level > 0...
- To: brad dot perry at amd dot com
- Subject: Re: 2.95 compiler bug with optimization level > 0...
- From: "Martin v. Loewis" <martin at mira dot isdn dot cs dot tu-berlin dot de>
- Date: Tue, 23 Nov 1999 01:21:11 +0100
- CC: brad dot perry at amd dot com, gcc-bugs at gcc dot gnu dot org, bug-gcc at gnu dot org
- References: <199911221645.KAA13679@loco.amd.com>
> Cool, that worked! I can't tell you how grateful we(AMD-K7) are!!!!
> Assuming b) might be the problem, what "common misunderstanding
> about C" are you referring to? Please include as much detail as you
> can.
People often assume that, in C, you can cast 'an address' to any type
you want and access it. This is incorrect; ISO C (i.e. ANSI C) is more
strict here. Basically, it disallows constructs like
float x;
void foo(long * y)
{
*y = 0;
}
int main()
{
foo((int*)&x);
}
The rule in ANSI C is simple: You must not access an object of some
type through a pointer of a different type (for exact rules, see ISO C
99, 6.5/7). In the case above, the access through y has undefined
behaviour, since a float object is access as a long object.
By the same pattern, the following code has undefined behaviour:
short foo()
{
short x[2];
x[0] = 1;
*(int*)x = 0;
return x[0];
}
Because this has undefined behaviour, the compiler can now make an
interesting optimization: If two pointers have different types, they
cannot possibly refer to the same object. So writing through a pointer
will not modify objects of a different type. As a result, the code
does not need to reload a value from memory when it could not have
changed.
egcs 1.1 already had this optimization as an option. With gcc 2.95, it
was turned on by default. Unfortunately, there is a lot of C code out
there that relies on the aliasing to work, so that this decision was
reverted for gcc 2.95.2.
Hope this helps,
Martin