[haiku-development] Re: Disabling Strict Aliasing for GCC4 Builds
- From: "Michael Lotz" <mmlr@xxxxxxxx>
- To: haiku-development@xxxxxxxxxxxxx
- Date: Fri, 18 Apr 2008 17:48:52 +0200
A follow up
Sorry, turned out not to be as short as I originally though. If you
don't really care about strict aliasing, you can safely skip this
message...
Real world example of a strict aliasing rule violation causing
unexpected behaviour: the Chart demo app in Haiku. When using Chart on
a GCC4 compiled Haiku that has strict aliasing enabled (i.e. prior to
r25016), you will notice that it doesn't draw anything (testing under
QEMU at least). When compiling Chart there are three warnings
concerning a break of strict aliasing rules. One is in ChartWindow.cpp
with the code:
BHandler *handler;
...
message->FindPointer("source", (void**)&handler);
This doesn't really look too wrong and in practice apparently doesn't
hinder functionallity either. I just show it here to point out what I
find quite limiting about strict aliasing rules. The "correct" way (and
this is only a GCC extension it turns out and not even officially
allowed by the standard) of doing that would involve doing the type
punning from BHandler ** to void ** for the FindPointer() call through
a union. This would result in the following code:
union {
BHandler *handlerPointer;
void *voidPointer;
} u;
message->FindPointer("source", &u.voidPointer);
And every instance where the handler pointer is accessed would then of
course need to be "u.handlerPointer". One could alternatively copy the
handler pointer out of the union after the call though so no further
changes to the function would be necessary.
Now this is not what is causing the drawing problems anyway. The cause
for that resides in ChartRender.cpp and is an implementation of a
simple approximation square root function:
float b_sqrt(float x) {
uint32 val;
float y,z,t;
float flottant, tampon;
flottant = x;
val = *((uint32*)&flottant);
val >>= 1;
val += 0x1FC00000L;
*((uint32*)&tampon) = val;
y = tampon;
z = y*y+x;
t = y*y-x;
y *= (float)4.0;
x = z*z;
t = t*t;
y = z*y;
t = (float)2.0*x-t;
return t/y;
}
This code does break strict aliasing in two places (it also breaks
coding style guidelines, but it's Be sample code...). First when
retrieving the uint32 representation of the float through "val = *
((uint32*)&flottant);" and the second time when setting the float
variable to the modified uint32 value again "*((uint32*)&tampon) =
val;". This generates the other two warnings. Appart from obviously
depending on a certain in-memory layout of a float, this code does
indeed break when strict aliasing is enabled. The compiler obviously
optimizes this function with the strict aliasing assumption which
causes these two sections to fail. Note that the uint32 variable "val"
and the float variables are not actually aliasing eachother, they are
stored in different memory locations. What is breaking the rules is the
"*((uint32 *)&flottant" part, as it makes a float pointer pointing to a
memory location (&flottant), and then makes a uint32 pointer out of it
pointing to the same memory location. This results in two pointers of
different (and incompatible) types pointing to the same location, which
obviously breaks the assumption that two pointers of different type
cannot do exactly that.
The above could be corrected in some different ways. For example a
union approach could be used where the float and the uint32 variables
would simply be put into the same union and then either of the union
members is modified:
{
...
union {
float flottant;
uint32 val;
} u;
u.flottant = x;
u.val >>= 1;
u.val += 0x1FC00000L;
y = u.flottant;
...
}
Which actually simplifies the code even and therefore is probably a
good thing to do anyway.
One could probably also implement it as actually moving around the
memory locations. For example using a macro around memcpy to make
things a bit handier:
#define COPY_VALUES(x, y) \
memcpy(&x, &y, MIN(sizeof(x), sizeof(y)))
And then use it like:
{
...
flottant = x;
COPY_VALUES(val, flottant);
val >>= 1;
val += 0x1FC00000L;
COPY_VALUES(tampon, val);
y = tampon;
...
}
But I am in fact not really sure if this doesn't just hide the problem
(as it works I suppose it doesn't).
As you see there are ways to get these situations corrected. But as
should be obvious from the first example of the FindPointer() method,
we will have lots of these cases. And I am not yet convinced that I
really like to do that kind of workaround in such common code.
Regards
Michael
- Follow-Ups:
- [haiku-development] Re: Disabling Strict Aliasing for GCC4 Builds
- From: Ingo Weinhold
Other related posts:
- » [haiku-development] Disabling Strict Aliasing for GCC4 Builds
- » [haiku-development] Re: Disabling Strict Aliasing for GCC4 Builds
- » [haiku-development] Re: Disabling Strict Aliasing for GCC4 Builds
- » [haiku-development] Re: Disabling Strict Aliasing for GCC4 Builds
- » [haiku-development] Re: Disabling Strict Aliasing for GCC4 Builds
- » [haiku-development] Re: Disabling Strict Aliasing for GCC4 Builds
- » [haiku-development] Re: Disabling Strict Aliasing for GCC4 Builds
- » [haiku-development] Re: Disabling Strict Aliasing for GCC4 Builds
- » [haiku-development] Re: Disabling Strict Aliasing for GCC4 Builds
- » [haiku-development] Re: Disabling Strict Aliasing for GCC4 Builds
- » [haiku-development] Re: Disabling Strict Aliasing for GCC4 Builds
- » [haiku-development] Re: Disabling Strict Aliasing for GCC4 Builds
- » [haiku-development] Re: Disabling Strict Aliasing for GCC4 Builds
- » [haiku-development] Re: Disabling Strict Aliasing for GCC4 Builds
- » [haiku-development] Re: Disabling Strict Aliasing for GCC4 Builds
- » [haiku-development] Re: Disabling Strict Aliasing for GCC4 Builds
- » [haiku-development] Re: Disabling Strict Aliasing for GCC4 Builds
- » [haiku-development] Re: Disabling Strict Aliasing for GCC4 Builds
- » [haiku-development] Re: Disabling Strict Aliasing for GCC4 Builds
- » [haiku-development] Re: Disabling Strict Aliasing for GCC4 Builds
- » [haiku-development] Re: Disabling Strict Aliasing for GCC4 Builds
- » [haiku-development] Re: Disabling Strict Aliasing for GCC4 Builds
- » [haiku-development] Re: Disabling Strict Aliasing for GCC4 Builds
- » [haiku-development] Re: Disabling Strict Aliasing for GCC4 Builds
- » [haiku-development] Re: Disabling Strict Aliasing for GCC4 Builds
- » [haiku-development] Re: Disabling Strict Aliasing for GCC4 Builds
- » [haiku-development] Re: Disabling Strict Aliasing for GCC4 Builds
- » [haiku-development] Re: Disabling Strict Aliasing for GCC4 Builds
- » [haiku-development] Re: Disabling Strict Aliasing for GCC4 Builds
- » [haiku-development] Re: Disabling Strict Aliasing for GCC4 Builds
- » [haiku-development] Re: Disabling Strict Aliasing for GCC4 Builds
- » [haiku-development] Re: Disabling Strict Aliasing for GCC4 Builds
- » [haiku-development] Re: Disabling Strict Aliasing for GCC4 Builds
- » [haiku-development] Re: Disabling Strict Aliasing for GCC4 Builds
- » [haiku-development] Re: Disabling Strict Aliasing for GCC4 Builds
- » [haiku-development] Re: Disabling Strict Aliasing for GCC4 Builds
- » [haiku-development] Re: Disabling Strict Aliasing for GCC4 Builds
- » [haiku-development] Re: Disabling Strict Aliasing for GCC4 Builds
- » [haiku-development] Re: Disabling Strict Aliasing for GCC4 Builds
- » [haiku-development] Re: Disabling Strict Aliasing for GCC4 Builds
- » [haiku-development] Re: Disabling Strict Aliasing for GCC4 Builds
- » [haiku-development] Re: Disabling Strict Aliasing for GCC4 Builds
- » [haiku-development] Re: Disabling Strict Aliasing for GCC4 Builds
- » [haiku-development] Re: Disabling Strict Aliasing for GCC4 Builds
- » [haiku-development] Re: Disabling Strict Aliasing for GCC4 Builds
- » [haiku-development] Re: Disabling Strict Aliasing for GCC4 Builds
- » [haiku-development] Re: Disabling Strict Aliasing for GCC4 Builds
- » [haiku-development] Re: Disabling Strict Aliasing for GCC4 Builds
- » [haiku-development] Re: Disabling Strict Aliasing for GCC4 Builds
- » [haiku-development] Re: Disabling Strict Aliasing for GCC4 Builds
- » [haiku-development] Re: Disabling Strict Aliasing for GCC4 Builds
- » [haiku-development] Re: Disabling Strict Aliasing for GCC4 Builds
- » [haiku-development] Re: Disabling Strict Aliasing for GCC4 Builds
- » [haiku-development] Re: Disabling Strict Aliasing for GCC4 Builds
- » [haiku-development] Re: Disabling Strict Aliasing for GCC4 Builds
- » [haiku-development] Re: Disabling Strict Aliasing for GCC4 Builds
- » [haiku-development] Re: Disabling Strict Aliasing for GCC4 Builds
- » [haiku-development] Re: Disabling Strict Aliasing for GCC4 Builds
- [haiku-development] Re: Disabling Strict Aliasing for GCC4 Builds
- From: Ingo Weinhold