Topic: Guaranteeing addresses vs. optimization in basic_string


Author: kanze@gabi-soft.fr (J. Kanze)
Date: 1996/03/22
Raw View
Concerning the class basic_string in the draft standard library: it has
just occurred to me that the function `reserve' is actually trying to do
two separate jobs.

1. Facilitate optimization.  When I call reserve, I am telling
basic_string that I expect to generate a string of `n' characters, and
that it should prepare for this.  Thus, in the classical implementation,
the class will immediatly allocate a buffer large enough, so that it
will not have to continuously reallocate each time I add a character.
On the other hand, one could easily imagine fragmented schemes in which
this function was a no-op.

2. Guarantee internal addresses.  Although the wording in the current
draft is a little vague in places, it seems clear that the intent is
that calling reserve guarantee the validity of things like the return
value of data() or at().  This implies that it can never be a no-op.
Also, since there is no function to undo this application of reserve, it
is still not clear (in the users minds, hopefully not in the final
standard) just how long this guarantee holds.

My question is: has anyone considered splitting this functionality into
two separate functions.  The exact effects of `reserve' would be
implementation dependant, the intend being to allow the optimization of
future memory allocation if this is relevant to the implementation.
Following the lead of iostream, the second function could be called
freeze, with a single parameter indicating whether the stream is being
frozen or unfrozen (freeze on or off).  The internal addresses are
guaranteed between the moment freeze is turned on and when it is turned
off.  This gives the user absolute control.

In the case of freeze, I would also suggest that calling a non-const
function on a frozen string result in an error (or undefined behavior,
which I don't like, but is more in keeping with the philosophy
underlying STL).  Note that in a fragmented implementation, freeze
should probably trigger the copy into a fixed array, so that you can
guarantee after that `&at( 0 ) == data()'.

Anyway, this is just a suggestion.  In implementing my own basic_string,
I have noticed that there is a lot of extra code (which actually gets
executed) simply to ensure the address guarantee from reserve, whereas I
suspect that most of the time reserve is called, it is only the
optimization that is needed (and when it is the address guarantee, even
the guarantee of reserve is not really sufficient).

Finally, I will admit that I have not considered the implications of
this (or anything else, for that matter) with regards to iterators.  I
believe that the intent is that a `char*' may serve as an iterator with
the classical implementation; in this case, any non-const function may
invalidate the iterator (unless, under the current rules, reserve has
been called).
--
James Kanze           (+33) 88 14 49 00          email: kanze@gabi-soft.fr
GABI Software, Sarl., 8 rue des Francs Bourgeois, 67000 Strasbourg, France
Conseils en informatique industrielle --
                            -- Beratung in industrieller Datenverarbeitung
---
[ comp.std.c++ is moderated.  To submit articles: Try just posting with your
                newsreader.  If that fails, use mailto:std-c++@ncar.ucar.edu
  comp.std.c++ FAQ: http://reality.sgi.com/austern/std-c++/faq.html
  Moderation policy: http://reality.sgi.com/austern/std-c++/policy.html
  Comments? mailto:std-c++-request@ncar.ucar.edu
]