On 9/9/07, Mark Mitchell <[EMAIL PROTECTED]> wrote: > Joe Buck wrote: > > >> In the case of "malloc", and assuming that all of the machinery for > >> malloc is hidden away in some piece of the program we're not talking > >> about, all three definitions apply. Each pointer returned by malloc is > >> an island unto itself; there's no conforming way to get there except by > >> using the pointer just returned. > > > > The key point is that the mechanism is hidden away. This might become > > more of an issue with LTO, so the question is how to make such guarantees > > make sense to an optimizer that can see the full program. > > Correct. The "malloc" attribute is only applicable to "malloc" because > we can't see how "malloc" is implemented. > > >> This seems like a useful optimization to me, and I understand that it > >> will work 99.99% of the time, and it's in the spirit of the standard -- > >> but how do we actually make it safe? If the attribute only applied to > >> other values returned from the same function, then it would be safe -- > >> but less useful. Can we do better? > > > > Maybe "pool", if exported, would have to be marked as aliasing the "new" > > calls, possibly with some new attribute "malloc_implementation" or > > something like that. > > It's worse than that: > > char *pool; > void set_pool(char *p) { pool = p; } > void *operator new(size_t s) { // return stuff from pool. } > > bool f() { > char *p = new char[1024]; > set_pool (p); > char *i = new char; > return (p == i); > } > > In other words, pointers from any part of the program can potentially be > "laundered" through set_pool and return via the new operator. I don't > see any way to make this fully safe, in general, without the limitation > I imposed: the no-aliasing guarantee only applies to the values returned > from the function called.
But in this case an access to *i through *p is invalid. [I suppose both new calls are actually different implementations here] Each new call starts lifetime of a new object, the previous object lifetime is terminated. Even comparing both pointers here for this reason would lead to undefined behavior. I know it's easy to play games to trick optimizers into doing something, but creating a not undefined testcase that goes wrong is hard ;) At least iff you remember to transform 'malloc' attributes to a dynamic type change if you inline a malloc. Richard.