This is the mail archive of the libstdc++@gcc.gnu.org mailing list for the libstdc++ project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: Supporting non-standard pointer types in STL containers



On Jul 7, 2008, at 6:08 AM, Paolo Carlini wrote:


Hi,

I quickly skimmed the patch and at the moment I'm mostly worried by the change to _Rb_tree_iterator, I don't think we can change the type (add a template parameter for the allocator) and keep the level of binary compatibility that we want.

Is the problem that you are concerned about cases of libraries which expose map<> types externally, passing maps between a library built with one version of the code and a library built with another? I had not thought of that. I was concerned primarilly about the ABI between compiled instances of _Rb_tree and the libstdc++-v3 library itself.


Additionally to that, which at the moment seems a show stopper to me, I'm also concerned that, even assuming the other concerns (about the layout of _Rb_tree_impl for example) turns out to be unfunded, it looks like we are going to break binary compatibility with the existing instantiations with Alloc != std::allocator, that seems bad, after all the efforts we made in the past to clean the containers to work also with stateful allocators (well, still not optimally performance wise, but that is another binary compatibility issue which must wait for the next break, unfortunately).

The following is true (I think): If the allocator used with an instance of _Rb_tree uses a standard pointer type, then the resulting code which is compiled is binary-compatible with the code created by the prior version of std_tree.h. A tree could be safely passed between object modules compiled with before/after versions of stl_tree.h, even when a non-standard allocator has been used. This is because _Rb_tree_node_base_T<_Alloc> is in that case the binary equivalent to _Rb_tree_node_base, and the execution of the old _Rb_tree_node_base code against instances of _Rb_tree_node_base_T<> would work. (Note that the _Alloc is not used as a member of the _Rb_tree_node_base_T<> - it is only used to decide the pointer type.) The same is true of the iterators. I will have to write a test which confirms this, but from looking over the code, and what the new templatized iterator and node_base_T types instantiate into, I think this is true. If not, I accept that I'll need to make it true.


I could strive to base the specialization on the pointer type of the _Alloc class, if that helps to address your concern. i.e. Rather than specialize for the use of _Rb_tree_node_base for all cases of _Alloc == allocator<T>, I'll base that on all cases where _Alloc::pointer = T*. That might make the code a little ugly. If there was such a thing as rebind() for pointer types, I could have made this clearer in the implementation.

One area where ABI compatibility is definitely broken is in the case where existing code was passing an allocator which used a non-standard pointer type. prior versions of stl_tree.h would effectively ignore that, but new versions would not, resulting in potentially different binary forms of the _Rb_tree nodes and iterators. However, this is a side effect of the change I am trying to introduce, and it is impossible to maintain this level of ABI and introduce this change. Is this particular ABI incompatibility acceptable?

One specific request about the design: Because of the difficulties making normal casts (const_cast<>, specifically) work in the resulting code, I had to adopt the convention of using cast_to<T>::using_const_cast(), so that the way casting works could be specialized for specific pointer types. The implications of this is that any code which intends to support custom pointer types has to make use of the cast_to<> class, rather than normal C++ casts, throughout that code. I was concerned about this, but have found it necessary. It's a more intrusive approach than I had originally planned, and I want to make sure that introducing this convention into container implementations will be acceptable.

Bob



Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]