From -4193229448209068134
X-Google-Thread: f78e5,574518e5c7a60feb
X-Google-Attributes: gidf78e5,public
X-Google-Language: ENGLISH,ASCII-7-bit
Path: g2news1.google.com!news4.google.com!newshub.sdsu.edu!cyclone.bc.net!news.alt.net!comp-std-cpp-robomod!not-for-mail
From: Pablo Halpern <phalpern@halpernwightsoftware.org>
Newsgroups: comp.std.c++
Subject: Re: Revised Allocator Proposal
Date: 29 Jul 2005 16:50:26 GMT
Organization: EarthLink Inc. -- http://www.EarthLink.net
Lines: 138
Approved: Fergus Henderson <fjh@cs.mu.oz.au>, moderator of comp.std.c++
Message-ID: <kibje1dvqt54imt1gfmli3a7j8d0top4u8@4ax.com>
References: <7ibbe1hu4omoqsfibanas46idf9u6i5hjo@4ax.com> <hinnant-1BAC6A.16393526072005@syrcnyrdrs-01-ge0.nyroc.rr.com> <fi2ge197lm9ttsmhb4r8v9cfjdmdq2joao@4ax.com> <hinnant-A468D2.15021328072005@syrcnyrdrs-03-ge0.nyroc.rr.com>
Mime-Version: 1.0
Content-Type: text/plain; charset=us-ascii
Content-Transfer-Encoding: 7bit
Return-Path: <devnull@stump.algebra.com>
X-Authentication-Warning: mulga.cs.mu.OZ.AU: fjh set sender to devnull@stump.algebra.com using -f
X-Robomod: STUMP, ichudov@algebra.com (Igor Chudov)
Delivered-To: std-c++@ucar.edu
X-Newsreader: Forte Agent 1.93/32.576 English (American)
X-Complaints-To: abuse@earthlink.net
X-Trace: newsread3.news.atl.earthlink.net 1122614910 24.215.251.54 (Thu, 28 Jul 2005 22:28:30 PDT)
NNTP-Posting-Date: Thu, 28 Jul 2005 22:28:30 PDT
X-Virus-Scanned: amavisd-new at ucar.edu
X-Virus-Scanned: amavisd-new at cs.mu.OZ.AU
X-Virus-Scanned: amavisd-new at cs.mu.OZ.AU
Xref: g2news1.google.com comp.std.c++:1559

Howard Hinnant <hinnant@metrowerks.com> wrote:

>> If swap exchanges the allocators, then the contents of
>> *mySharedStringPtr are no longer shared!  Worse, mySharedStringPtr
>> continues to point to a shared memory object which now contains a
>> pointer to unshared memory.
>
>But the solution to this problem is already in common use today (and is 
>also in your paper):
>
>    void munge(std::string* s) {
>        std::string tmp(s->get_allocator());
>        // Create a value for tmp using segments of *s
>        s->swap(tmp);  // Reflect changes into s
>    }
>
>Sorry, but I'm not swayed by this argument.  Being careful in this way 
>to support non-equal allocators is old news to me (I've been doing it 
>for years).

But most people *haven't* done this for years.  I work with a lot of
intermediate-level C++ programmers and I can tell you that most of them
don't even know the purpose of the allocator argument in container
constructors!

If there were two types of standard swap (e.g. swap_value and
swap_move), then people would eventually learn to pick among them
carefully.  A well-written function prototype would have an associated
comment stating whether or not the allocator of the object being passed
in is likely to change, and this issue would be mute.

If I call a function that was written 5 years ago (or yesterday, even),
and if that function uses swap, and if swap exchanges the allocator, I'm
sunk.  Yes, there will be errors caused by the loss of the nothrow
guarantee, but much more rarely, IMO, because, as I show in the paper,
most of that code remains safe with the rollback guarantee. (I
acknowlege that the example in your previous post is an exception)

>> There are
>> two main types of useful allocators: arena allocators that provide
>> higher performance over a limited region of the program and special
>> allocators that provide shared memory allocation or other special
>> allocation services.
>
>I've built arena allocators and not felt the need for such a drastic 
>redesign of the std::lib to make them safe and efficient.  If two 
>containers which are swapped (exchanging memory) also swap allocators, 
>the code continues to work whether or not the two allocators are equal 
>(point to the same arena).

I'd be curious to know how you control when memory is returned from the
arena allocator if the allocator can suddenly end up used by an
unrelated object.  Have you ever written an arena allocator that
allocates from a stack buffer?  You should; it's fun and very fast.  But
don't do it if you expect the allocator to live after the stack frame is
gone.

You seem to be dismissing the need to control allocator lifetime, yet in
our work we need this all the time (the stack-based allocators is one of
our staples).  I say from experience as a client (not just a library
developer) that within a short time, the principle of allocators not
changing gets into your bones!  The question is simple: do you want
control over memory or not?  If not, then don't use allocators.  If so,
then you need to ensure that the allocator is used when you want it and
ONLY when you want it.  Otherwise, what's the point?

>I've not built shared memory allocators.  But I have had thoughtful 
>discussions with Ion Gaztanaga, author of Shmem on this subject.  I 
>understand that problems arise when different containers from different 
>shared memory segments are swapped.  But I also understand that this 
>problem does not exist when both shared memory allocators are in the 
>same segment (even if they are not equal).

So? What if one of the allocators isn't even a shared memory allocator,
as in my example?  The fact that *some* unequal allocators have *some*
level of compatibility isn't very compelling.

>O(N) swaps are no more correct than O(1) swaps with unequal allocators.  
>Either decision can result in broken code.  Hobbling all container swaps 
>with O(N) behavior when two allocators are not equal, just to support 
>the one case of different-segment shared memory allocators does not seem 
>like a good deal to me.  The existence of unequal arena allocators, and 
>same-segment but unequal shared memory allocators that will benefit from 
>O(1) swaps, combined with the O(N) performance gain and nothrow 
>exception guarantee strongly tilt the decision in favor of O(1) swap 
>imho.

Seems like a stretch to me. Remember, since allocators are not part of
the *type* of the object, the unequal allocators my not even belong to
the same family (i.e. their allocator_implementation objects may belong
to different derived classes). In my experience, this is more often the
case than not.

>Additionally, if container::swap is always O(1), then clients needing an 
>O(N) variant of the idea (say for different-segment shared memory 
>containers) can very easily accomplish it with an explicit 
>copy-assign-assign sequence -- no need to introduce a new name like 
>swap_value.  If he also needs strong exception safety, changing that to 
>copy-copy-swap-swap isn't overly burdensome.  This is all existing 
>interface, no new stuff to learn.

Everything in the standard library can be accomplished in user code.  So
what?  If its not a standard function, then it won't become a standard
practice.  Even if I accept that swap() should do a swap_move (which I
don't), a version of swap that does a swap_value is essential to
promoting the writing of correct code (i.e. where the programmer
thoughtfully chooses the correct swap).  Moreover, swap_value can be
optimized for certain cases.  For example vector<pod-type>::swap_value
can be optimized by the library vendor to use much less auxiliary
storage.

>Otoh, if swap is sometimes O(N), the client that needs O(1) swap must 
>now rely on a new function with a different name (swap_move) that has 
>the functionality he normally expects out of swap (since 1998).  This 
>seems like an error prone interface to me.

The 1998 standard swap has the qualities of both swap_move and
swap_value because the standard allows all allocators of a given type to
be assumed equal.  Which ever form of swap we choose will break
someone's 1998 assumption.  Even in implementations that allow unequal
allocators, some vendors chose the swap_move (nothrow) semantic while
others chose the swap_value (allocators don't change) semantic.

Unfortunately, I think the swap discussion is detracting attention from
other parts of the proposal.  Even if I lose the swap argument, I
believe the rest of the proposal has merit and should be discussed
(unless you think it's ready for adoption as-is :-) ).

Pablo Halpern                 phalpern@halpernwightsoftware.com
Author: The C++ Standard Library from Scratch
http://www.halpernwightsoftware.com/stdlib-scratch

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]



