discuss-gnustep
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Test on Ubuntu 12.04 64bits


From: David Chisnall
Subject: Re: Test on Ubuntu 12.04 64bits
Date: Sun, 27 May 2012 18:23:22 +0100

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



reply via email to

[Prev in Thread] Current Thread [Next in Thread]