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

Reply via email to