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.

Reply via email to