|
Boost : |
From: Peter Dimov (pdimov_at_[hidden])
Date: 2003-08-25 06:57:03
E. Gladyshev wrote:
> --- Peter Dimov <pdimov_at_[hidden]> wrote:
>
>> In this context, an allocator parameter is only an excuse for
>> implementors
>> to avoid doing the necessary work to make function<> useful out of
>> the box. "You can always use a custom allocator", right?
>
> Considering the variety of real life requirements and platforms, it
> is not practical to make a library that work out of the box.
The danger in that statement is that it looks obvious, but it's not. It is
true in some sotuations (not as frequent as is generally believed) and false
in others, and when it doesn't really hold but is axiomatically accepted as
truth, it serves as exactly the excuse I was talking about. "It is not
practical to make a library that works out of the box, so users should be
happy that they are getting a library that can be made to work with a
"small" additional investment. Of course we'll gladly sell you the
additional bits and pieces."
It is interesting to compare the C++ approach with the Java approach to
memory management in this context. C++ "pragmatically" accepts that the
shipped malloc is often inadequate and provides several types of hooks that
you can use to work around the problem. Java does not. If the JVM has a
broken memory manager you lose and can do nothing about it. This gives C++ a
short term advantage, but in the long term Java wins, since JVM implementors
have no choice but to optimize their memory managers till they are blue in
the face.
Bugs that have no workarounds are always fixed first. :-)
> That is why STL has allocators. In one project, if STL did not have
> allocators, I would have to implement my own containers. I was so
> happy that I didn't have to do it.
So far my experience indicates that people only bother with allocators when
std::allocator is inadequate, i.e. slow. Your case may, of course, be
different. It happens sometimes.
> At least a library should be consistent about memory management.
This is an arbitrary requirement.
> The issue is how consistent boost is about it (STL is very
> consistent)? It seems that boost doesn't have any idea about how it
> manages its memory.
A fairly aggressive way to state it, but I see your point. It is true that
Boost does not impose any requirements on how the particular libraries
obtain and manage their memory. But you need to realize that "do nothing"
can be a conscious design decision. Lack of strict requirements means more
freedom for the implementations to do what they consider best.
As an example, consider a hypothetical std::vector<T> that does not have an
allocator argument and "has no idea how it manages its memory." Do you see
the implications of that?
1. vector::resize and vector::reserve can now realloc in place since they
can talk directly to the memory manager.
2. On many implementations, vector<T> can now be made as efficient as new
T[], since new T[] often stores the equivalent of size() and capacity()
anyway to allow delete[] to do the right thing.
> For example if a boost class X uses std::list, does it have to expose
> the std::list<> allocator or should it use the standard
> std::allocator<>.
> template<typename T>
> struct X
> {
> std::list<T> l;
> };
>
> OR
>
> template<typename T, typename A=stl::allocator<T> >
> struct X
> {
> std::list<T, A> l;
> };
>
> Which definition is more friendly to boost?
The correct answer depends on X's interface. Your toy example is not a good
illustration as this kind of "interface" is rarely seen.
> Is it allowed for a boost libarary to use global new/delete? If so,
> should it be documented?
Boost libraries are allowed to use the C++ language without restrictions.
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk