Boost logo

Boost :

From: Joaquin M Lopez Munoz (joaquin_at_[hidden])
Date: 2006-03-13 18:02:46


Markus Schöpflin <markus.schoepflin <at> comsoft.de> writes:

>
> Joaquín Mª López Muñoz wrote:
>
> > 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:
>
> [...]
>
> > 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.
>
> Seems we're on the right track, but unfortunately adding the manual
> instantiations to the files in question didn't help.
>
> I did some further debugging; here is what I got. Maybe you can spot
> something that will help.
>
[...]

This is more of the same: two distincts objects of the same type
extended_type_info_typeid<
boost::multi_index::detail::index_node_base<int> > are trying
to self-register into tkmap, which is asserted.
The problem can be traced down to the following member
function of extended_type_info_typeid_1 (lines 94-98 of
extended_type_info_typeid.hpp):

    static extended_type_info *
    get_instance(){
        static extended_type_info_typeid_1<T> instance;
        return & instance;
    }

Two static "instance" objects are created in each translation
unit, which is obviously a bug in the compiler.
I've been reading the following:

http://nf.apac.edu.au/facilities/software/CXX/ugutmpl.htm

and looks like the bizarre template instantiation model
of Compaq C++ would allow us to:

1. leave only the declaration of get_instance() in
boost/serialization/extended_type_info_typeid.hpp.

2. Move the definition of get_instance() to
libs/serialization/extended_type_info_typeid.cpp

Is this correct? If so, seems like the duplicate
"instance" object should disappear this way. Can you give
this a try?

>
> Markus
>

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