Re: Reasons for not standardizing policy based smart pointers
On Jun 4, 11:33 am, James Kanze <james.ka...@gmail.com> wrote:
On Jun 3, 11:21 pm, Lance Diduck <lancedid...@nyc.rr.com> wrote:
On Jun 3, 12:56 am, bda...@acm.org (Beman Dawes) wrote:> Gennaro Prota wrote:
Given that we cannot even reliably use std::string and such as a
common interface between libraries should give one pause.
They don't pose any problems for us. They're part of the
standard, and every compiler we use implements them.
The most popular yet least sexy way of "policy based programming" is
by build options. In all compilers I know of, I can swap out
std::library implementations. And the only thing specified by the
standard is certain minimum behaviors and the interface. Which it
should be. But everything other feature is a dreaded "build option"
So we have this scenario:
namespace JiffyXMLDOMParser {
class IDom;
std::tr1::shared_ptr<IDom> parse(std::string const&);
}
and the implementer guarantees jiffyness for certain platforms, say
Sun Ws6U2 using XYZ build options
namespace LightningCalc {
typedef std::deque<std::pair<std::string,double> > tickdata;//stock
ticker info
typedef std::deque<double> result;
result calc(tickdata const&);
}
and the implementor guarantees lighting results for certain platforms,
say Sun Ws6U2 using ABC build options
Now we have the poor integrator, who is NOT a C++ guru and shouldn't
have to be, facing this scenario:
namespace App //gets tick data from XML feed, and does a calculation
{
void doit(){
using namesapce JiffyXMLDOMParser;
using namespace LightningCalc
std::string datastr=getTONSofdata();
std:tr1::shared_ptr<IDom> p_res=parse(datastr);
tickdata tdata=ConvertDOMtotickdata(p_res);
result calc_res=calc( tdata);
}
}
Now the writer of App
a) has to find the magic mix of XYZ and ABC that would get this to
compile and link in the first place (and that may not even be
possible)
b) this mix does not satisfy either library requirement, so the
guarantees are off
c) the library writers, themselves not C++ build masters, just chose
interface types (std::deque, std::tr1::shared_ptr, etc) and build
options that made their individual benchmark suites go fast. In other
words, the implementation is exposed in the interface.
d) the library writers, using the logic that std::foobar is standard
and comes with the compiler --therefore it must be applicable for all
cases -- cannot foresee case where std::foobar would not be
appropriate. For example, each library writer wants std::string: DOMs
are usually large and read only, so COW implementation of std::string
is a good choice. For tick data, SSO implementations of std::string
are your best choice. COW and SSO are part of those build options.
And I have not even delved into whether the libraries ship in binary
form or not, or what the threading model is.
Had the implementers of JiffyXMLDOMParser and LightningCalc chosen
types that do not depend on build options, then everybody is happy.
But they didn't, and we are left with a mess.
There are
far more stringent requirements for using a C++ type as a common
demominator between libraries than "it doesnt change its type."
I have heard repeated often times, that one should be able to use
std::container and string ,and now shared_ptr, or other std:: types as
common "library vocabulary types." What happens in practice is that
designers actually start doing this without thinking it through --
even for in house code just shared amongst departments -- and suddenly
there are wars about an implementation of std::string or whatever.
How can their be wars about this? You don't implement
std::string; the compiler does. So you get what the compiler
gives, and live with it.
There are now compilers that ship with multiple versions on the
std::string available. But yes I agree with you. std::containers and
steams should be locked down by the compiler, and if you want
something different, you put that in a different namespace and deal
with it.
For
example, one guys library works best with COW strings, and another
with Copy Always strings.
Which means that one guy's library works best with compiler A,
and the other guy's with compiler B. But both work with both
compilers.
Now there is an ensuing battle over just
whose std library implementation are you going to use for the
integration of the two?
You don't have a choice? The library is part of the compiler,
and only an idiot would try to change it.
This is a real world scenario:
Sun uses a implementation of the std library that they acquired from a
vendor. They modified it somewhat, and shipped it. It works great in
single threaded mode, and back then there were not too many users
either of std::string nor of MT mode.
Their std::string was a COW implementation, and used a SINGLE global
mutex for ALL std::string's in your program.
Well you can imagine the trouble that some developers had, when they
did the supposed "right thing" and switched from their proprietary
strings to the std:: version, in all their MT programs. Spending 20%
time in contention dealing with strings was the numbers my teammates
dealt with.
Still believing that std:: was the "right thing" they instead switched
the std librarys itself to a version that worked better for this
scenario, typically STLport. Sun then added STLPort as a build option.
Some developers just switched back to their proprietary strings, and
cursed C++. Some, started using std::vector<char> for strings. Some
just insisted on their build options for all. I used a thing very
similar to Alexandreascu's FlexString.
But in the "idiot" case, I do know of a developer actually convinced
his company to switch to a weird version of the std:: libs, where all
policies (including allocators) are determined at runtime as
constructor args. I would take the "build option policies" over this
case -- at least with "build option policies" you have a ghost chance
of actually figuring out what the problem is.
What does this have to do with smart pointers? Policies are going to
be there somehow, someway, whether as hard coding, template
parameters, constructor args, build options, or environment settings.
boost::shared_ptr policies are a combination of build options, hard
coding, and constructor args, but somehow insist it is not "policy
based." My personal version of shared pointer moved boost build option
and hard coding policies to template args, and then uses a form of
template aliasing to make it conform to the standard.
Lance
---
[ 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.comeaucomputing.com/csc/faq.html ]