On 27 May 2012, at 18:03, Fred Kiefer wrote: > You access an array of four chars in the middle of a structure and want to > use it as a pointer to an UInt32. This may work on most machines, but there > is no guarantee that it will on all. You rather should implement the > conversion to a SInt32 manually. On the other hand, that structure was > carefully crafted to align these arrays correctly as long as the structure > itself was aligned that way.
That's not the issue. In C, integer and floating point pointers are not allowed to alias. The compiler is therefore free to assume that any pointer to a floating point variable does not reference the same underlying memory as any integer variable. This was especially important for good performance on something like the Alpha, where the integer and floating point pipelines were entirely different and moving things between the two was expensive, and optimisations based on these assumptions can still give a 5-10% performance boost on a lot of code with modern architectures. If you do have some memory that violates these rules, then you must explicitly cast via void*, which informs the compiler that this dereference may violate the normal aliasing rules. Note that this only applies to C, in C++ the rules are far, far more complicated, and I don't think anyone in the world actually understands them - I've been involved in discussions where two people in WG21 were uncertain whether a piece of code violate them or not. GNUstep violates this rule in a number of places[1], which is why GNUstep Make adds -fno-strict-aliasing to the default set of CFLAGS. Note that, for the alignment part of the problem, C11 adds an _Alignas keyword, which allows you to define a type that is interpreted as one type but with the alignment of another. You would use this with a union of the two types to get a struct field that had (at least) the minimum alignment required by two types. David [1] Unfortunately, while it is fairly easy to say that a particular piece of code does violate the rules, it is much harder to say that one doesn't, and unless you are really in CPU-bound code, it's generally better to turn it off than to assume you managed to get it right everywhere. Inlining, especially cross-module inlining, can suddenly make violations of these rules alter the semantics of the program. Yes, this was a stupid thing to put in the spec. Blame the people with Fortran-envy. -- Sent from my Difference Engine _______________________________________________ Discuss-gnustep mailing list [email protected] https://lists.gnu.org/mailman/listinfo/discuss-gnustep
