On Mon, Jan 12, 2009 at 12:03 AM, Raoul Gough <raoulgo...@yahoo.co.uk> wrote: > Richard Guenther wrote: >> >> On Sun, Jan 11, 2009 at 7:59 PM, Raoul Gough <raoulgo...@yahoo.co.uk> >> wrote: >> > > [snip] >>> >>> I guess the situation is more complicated in C++, which has explicit >>> destructors. Consider the following example, which is getting closer to >>> the >>> problem that originally got me interested in this subject: >>> >>> void** global_free_list = 0; >>> >>> inline void operator delete(void* p2) throw() >>> { >>> // Save "next" pointer in re-used client storage. TODO - check for NULL >>> *static_cast<void **>(p2) = global_free_list; >>> global_free_list = static_cast<void **>(p2); >>> } >>> >>> double foo(double* p1) >>> { >>> double result = *p1; >>> delete p1; >>> return result; >>> } >>> >>> Now, after inlining, this example looks very similar to my original one, >>> except we have pointers of type double* and void** sharing the same >>> storage >>> space instead of int* and double*. Note - we can easily ensure that the >>> corresponding operator new() always allocates storage suitably sized and >>> aligned for a void*. >>> >> >> This is also invalid. You have to use placement new to change the dynamic >> type of memory. >> >> > > Yes, I guess that makes sense. I've modified the example like this: > > #include <new> > > void** global_free_list = 0; > > inline void operator delete(void* p2) throw() > { > // Save "next" pointer in re-used client storage > new (p2) (void *) (global_free_list); > global_free_list = static_cast<void **>(p2); > } > > double foo(double* p1) > { > double result = *p1; > delete p1; > return result; > } > > > I've included the complete alias debug output below. This now includes > global_free_list in the may-alias lists, which is interesting. Also there is > a NULL-pointer check and branch, but I assume another optimization phases > could, under some circumstances, remove this. For example, if foo() started > with assert(p1) then this NULL pointer check would be redundant. That would > leave it with more or less the same code tree as before, aside from the > differences in the aliasing information. > > So how is this example looking now? Does the alias analysis mean that g++ > will never reorder the read and write via p1 and p2?
Yes, as that would now be an invalid thing to do. Note that for C there is no way to do "placement new", but the memory model of C only has static typing, not the notion of a dynamic type. Which is why some people (including me) say you cannot do a C conforming implementation of malloc that ever re-uses memory. Richard.