On Tue, 2007-11-06 at 09:32 -0800, Joe Buck wrote: > On Wed, Nov 07, 2007 at 04:06:11AM +1100, skaller wrote: > > On Tue, 2007-11-06 at 07:49 -0800, Joe Buck wrote: > > > Now it appears that you want to make some kind of intermediate assumption > > > (semi-strict aliasing?), where pointers of different types are allowed to > > > alias while ints can't alias with pointers. > > > > Yes. I want layout compatible types to be allowed to alias but > > not others. In other words, where the access would be valid > > provided it isn't optimised, don't optimise it. But where > > the access would not be valid, optimise away. > > The problem is that this doesn't appear to be what anyone else wants.
Yes, but that may be because they have no idea what they need because at the moment the optimisations are defeated in other ways, such as by crossing subroutine or translation unit boundaries. > Your rule would still break some existing code that needs > -fno-strict-aliasing, but allows some aliasing that the C standard > does not allow. Yes, so perhaps a different switch would avoid that. [Note again this is not a feature request, just a discussion where I am trying to learn what gcc does] > It seems to be a rule that is tailored to your > personal programming style. It seems that way, but you may be surprised how much code 'legitimately' breaks the rules. > > In C++ this is essential because constructable types cannot > > be aliased in a union. This problem doesn't arise like that > > in C. > > One way to do this in C++ is to derive the different representations that > might appear in your "union" from a common base class, and use placement > new to lay them out. I don't understand. You cannot put ANY constructable types in a union. So for example: struct X { string x; }; cannot go in a union, even though no constructor is written, because 'string' has a constructor, so X has one generated, and thus X is also constructable. Using a cast instead of a union is another way to solve this, but then as we know the strict aliasing rules might get in the way. Using 'placement new' still requires a cast, and it doesn't solve the problem: I need an *expression* which is an initialised first class array. Thats what the casts are for: making first class initialised array expressions. It works, even with strict aliasing on.. at the moment. A fast conforming solution isn't possible AFAIK. [BTW: this is only one of the aliasing hacks I use] > There are probably other ways as well. Your > hairy casts are, IMHO, quite risky. I know. I don't like it, but this is the best alternative. C++ is broken in a number of places. This is one of them. > You are misusing C++, I'm afraid, and there are no promises that > some day a new optimization won't break your code. I know, but as I said, C++ is broken and so there is no help for it. In this case the safe alternative is going to be much slower and may not work: struct X { T data[10]; X(T d1, T d2, ... ) { data[0]=d1; data[1]=d2; ... } }; This will not work unless T has a default constructor. It is also slow, because the default constructors are all applied first, then assignments done. Whereas my hacked up code initialises the array directly by remodelling it as a set of discrete variables, then aliasing them as an array. C++ 2010 may solve this by finally providing the inline array class I required ~15 years ago. > I suggest > consulting a C++ experts' forum, like comp.lang.c++.moderated, > for ideas on how to do what you want to do in standard C++. Thanks, but I AM a C++ expert, and I have already asked. [Boost's aligned_storage solves one of my problems, but it isn't portable, and it is also very ugly to use .. I also need the C++ code my compiler generates to be readable] -- John Skaller <skaller at users dot sf dot net> Felix, successor to C++: http://felix.sf.net