Boost logo

Boost :

From: Joaquín Mª López Muñoz (joaquin_at_[hidden])
Date: 2006-03-13 09:17:19


Markus Schöpflin ha escrito:

> Joaquín Mª López Muñoz wrote:
>
> > Hello Markus
> >
> > Markus Schöpflin ha escrito:
> >
> >> JOAQUIN LOPEZ MU?Z wrote:
> >>
> >> [...]
> >>
> >>> The test used to work, but has hundergone a significant
> >>> change that I've got the hunch might be related to
> >>> its currently failing: previously all serialization
> >>> tests were performed in a single translation unit
> >>> named test_serialization.cpp, while now the code has
> >>> been split (for reasons irrelevant to this discussion) into
> >>> two files test_serialization1.cpp and test_serialization2.cpp.
> >>> Does this ring some bell?
> >> [...]
> >>
> >> This is most probably caused by having multiple instances of some static
> >> object, which in turn is caused by a limitation of the template
> >> instantiation model used. (All automatically instantiated templates are
> >> placed in the output object and given internal linkage.)
> >>
> >> If you can identify the static object in question, adding a manual
> >> instantiation of the enclosing template will work around this, because
> >> those will be placed in an external template repository with external linkage.
> >
> > That's precisely what I'd like to ask you :) Could you trap the assertion
> > and dump the stack trace? Hopefully, that'll reveal the type of the
> > object which is causing the problem.

[...]

> I had a look at extended_type_info_typeid_1::get_instance::instance and
> oserializer::instantiate::instance but those look correct. Hmmm...

I think I know what's going on: the calls to tkmap::insert are generated
fon the constructors of automatically generated extended_type_info_typeid<>
instantiations. For the test program we're dealing with, the complete
list of instantiation arguments of extended_type_info_typeid<> is:

boost::multi_index::detail::index_node_base<int>
boost::multi_index::detail::bucket_array<boost::detail::allocator::partial_std_allocator_wrapper<int> >
boost::multi_index::detail::index_node_base<std::pair<int,int> >
boost::multi_index::multi_index_container<...1...>
boost::multi_index::safe_mode::safe_iterator<...1...>
boost::multi_index::multi_index_container<...2...>
boost::multi_index::safe_mode::safe_iterator<...2...>
boost::multi_index::multi_index_container<...3...>
boost::multi_index::safe_mode::safe_iterator<...3...>
std::pair<int,int>
boost::multi_index::multi_index_container<...4...>
boost::multi_index::safe_mode::safe_iterator<...4...>

12 types in total. Of these, only the first one, boost::multi_index::detail::index_node_base<int>,
is shared between test_serialization1.cpp and test_serialization2.cpp. This
sharing, according to your reasoning about automatically instantiated
templates being given internal linakge treatment, is what is causing the
duplicate call to tkmap::insert making the assert trigger. The stack trace
you've provided corroborates this.

You said in a previous mail:

> If you can identify the static object in question, adding a manual
> instantiation of the enclosing template will work around this, because
> those will be placed in an external template repository with external linkage.

The enclosing template is then, if I'm not wrong, the following:

boost::serialization::extended_type_info_typeid<
  boost::multi_index::detail::index_node_base<int> >

Could you add a manual instantiation of that to your local copy of the test
and check? Also, I'm not entirely sure by you mean by "manual
instantiation", but once you've done the test I hope you can refer me to
your code.

Thank you again for your continuous support,

Joaquín M López Muñoz
Telefónica, Investigación y Desarrollo


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk