On Thu, Apr 30, 2009 at 1:57 AM, Strontium <[email protected]> wrote:
> That said, I don't like C99, because of the issues it introduces with
> regard to strict aliasing. I still don't understand why the language
> specification cares about making life easy for an optimiser more than it
> cares about the correctness of the code and the directions of the
> programmer (regardless of how portable the resulting code may be).
That's not a C99 issue. You get the same optimization behavior
from gcc with non-C99 code. The optimization happened to be
introduced at about the same time as C99 support, but that was
merely a coincidence.
Visual studio will not perform this optimization. Intel's compiler will,
but Intel's compiler avoids it in pretty much every case where gcc
would be able to issue a warning. You thus can get burned when
using Intel's compiler, but you'll never see a warning.
> But that said, if those issues don't effect this project, it isn't a
> problem. For embedded software I always end up using pointer casts to
> make certain algorithms more efficient, invariably I run afoul of strict
> aliasing checks. So I manually turn this "feature" off with
> -fno-strict-aliasing
I personally learned about the "feature" when dealing with a bug
in a C library for an embedded OS. It was something like signbit(),
which casted from double* to short* to look at the raw bits.
Everybody on the OS team was horrified to learn how C works. :-)
I kind of like the feature now, along with "restrict" pointers, because
the extra performance is nice.
Five ways to fix your code:
You can memcpy() the data. (careful: do not memcpy the pointer!)
Remember that gcc recognizes memcpy. For small things, gcc will
replace memcpy with simple load/store instructions. It's very fast.
You can access the data as type char. The key thing here is that the
actual access must be via a char* or similar. You might suppress the
warnings with multiple casts, but that doesn't solve the problem. It's
not OK to do *(int*)(void*)(char*)(void*)some_float_ptr or similar.
The gcc developers promise to let you cheat with a union. I really wish
they hadn't, because I'd greatly prefer the optimization in this case.
Declare your stuff as a union and go to town. Note that your typical case
needs to be a pointer to a union containing int and float, not a union of
pointers to different types.
You can cheat as I did, abusing assembly constraints. Like so:
#define MEMORIZE(ptr) __asm__ __volatile__("":"=r"(ptr):"0"(ptr):"memory")
You can use __attribute__((__may_alias__)) on things. This grants
them the power of char.
_______________________________________________
Openocd-development mailing list
[email protected]
https://lists.berlios.de/mailman/listinfo/openocd-development