Hi, I'm trying to work on some code I haven't looked at in some time and in debug builds (with gcc 4.4.3) I keep getting an undefined symbol: boost::serialization::version<boost::multi_index::detail::serialization_version<bio::BindingHit<bio::BindingModel>
::value
I can't work out where this is getting referenced and why the compiler is not instantiating it there? Can anyone point me in the right direction? I'm using boost SVN revision 64053. Thanks, John.
AMDG On 2/15/2011 11:43 AM, John Reid wrote:
I'm trying to work on some code I haven't looked at in some time and in debug builds (with gcc 4.4.3) I keep getting an undefined symbol:
boost::serialization::version<boost::multi_index::detail::serialization_version<bio::BindingHit<bio::BindingModel>
::value
I can't work out where this is getting referenced and why the compiler is not instantiating it there? Can anyone point me in the right direction? I'm using boost SVN revision 64053.
Most likely, the out of line definition was forgotten. It's easy to forget for integral constants defined in the class body because it often isn't needed. In Christ, Steven Watanabe
On 15/02/11 20:09, Steven Watanabe wrote:
AMDG
On 2/15/2011 11:43 AM, John Reid wrote:
I'm trying to work on some code I haven't looked at in some time and in debug builds (with gcc 4.4.3) I keep getting an undefined symbol:
boost::serialization::version<boost::multi_index::detail::serialization_version<bio::BindingHit<bio::BindingModel>
::value
I can't work out where this is getting referenced and why the compiler is not instantiating it there? Can anyone point me in the right direction? I'm using boost SVN revision 64053.
Most likely, the out of line definition was forgotten. It's easy to forget for integral constants defined in the class body because it often isn't needed.
So you're saying this is most likely a bug in the serialization library? I can't remember the documentation asking me to define this symbol. Also I'm mystified as to why it is only a problem in the debug build. I'm fairly confident it has been working with both builds using older boost releases. Is there any way I can work out where the symobl is referenced? I still can't work out what's going wrong but I'm suspicious it somewhere in the following code. I think this is the only code that can match the undefined symbol, although obviously boost::serialization::version is not something I've declared. namespace bio { /** A set of binding hits indexed by various criteria. Defines a multi_index container type. */ template< typename B > struct BindingHitSet { struct position { }; struct binder { }; struct prob { }; typedef boost::multi_index_container< BindingHit< B >, boost::multi_index::indexed_by< // ordered by position (and other members) boost::multi_index::ordered_non_unique< boost::multi_index::tag< position >, boost::multi_index::identity< BindingHit< B > > >, // ordered by binder boost::multi_index::ordered_non_unique< boost::multi_index::tag< binder >, boost::multi_index::member< BindingHit< B >, B *, &BindingHit< B >::binder > >, // ordered by binding prob boost::multi_index::ordered_non_unique< boost::multi_index::tag< prob >, boost::multi_index::member< BindingHit< B >, double, &BindingHit< B >::p_binding > > > > type; }; /** Serialization to an Archive. */ template< typename B, typename Archive > void serialise( Archive & ar, const typename BindingHitSet< B >::type & t ) { unsigned n = t.size(); ar << n; for( typename BindingHitSet< B >::type::const_iterator h = t.begin(); t.end() != h; ++h ) { ar << *h; } } /** Deserialization from an archive. */ template< typename B, typename Archive > void deserialise( Archive & ar, typename BindingHitSet< B >::type & t ) { unsigned n; ar >> n; t.clear(); while( 0 != n ) { typename BindingHitSet< B >::type::value_type value; ar >> value; t.insert( value ); --n; } } /** Serialization to a file. */ template< typename B, bool binary > void serialise( const typename BindingHitSet< B >::type & t, const boost::filesystem::path & file) { typedef B binder_t; if( binary ) { boost::filesystem::ofstream stream( file, std::ios::binary ); boost::archive::binary_oarchive ar( stream ); serialise< binder_t >( ar, t ); } else { boost::filesystem::ofstream stream( file ); boost::archive::text_oarchive ar( stream ); serialise< binder_t >( ar, t ); } } /** Deserialization from a file. */ template< typename B, bool binary > void deserialise( typename BindingHitSet< B >::type & t, const boost::filesystem::path & file) { typedef B binder_t; if( binary ) { boost::filesystem::ifstream stream( file, std::ios::binary ); boost::archive::binary_iarchive ar( stream ); deserialise< binder_t >( ar, t ); } else { boost::filesystem::ifstream stream( file ); boost::archive::text_iarchive ar( stream ); deserialise< binder_t >( ar, t ); } } } //namespace bio Thanks, John.
On 16/02/11 09:47, John Reid wrote:
On 15/02/11 20:09, Steven Watanabe wrote:
AMDG
On 2/15/2011 11:43 AM, John Reid wrote:
I'm trying to work on some code I haven't looked at in some time and in debug builds (with gcc 4.4.3) I keep getting an undefined symbol:
boost::serialization::version<boost::multi_index::detail::serialization_version<bio::BindingHit<bio::BindingModel>
::value
I can't work out where this is getting referenced and why the compiler is not instantiating it there? Can anyone point me in the right direction? I'm using boost SVN revision 64053.
Most likely, the out of line definition was forgotten. It's easy to forget for integral constants defined in the class body because it often isn't needed.
Digging a bit deeper in the boost code I found the undefined symbol in boost/serialization/version.hpp: // default version number is 0. Override with higher version // when class definition changes. template<class T> struct version { template<class U> struct traits_class_version { typedef BOOST_DEDUCED_TYPENAME U::version type; }; typedef mpl::integral_c_tag tag; // note: at least one compiler complained w/o the full qualification // on basic traits below typedef BOOST_DEDUCED_TYPENAME mpl::eval_if< is_base_and_derived<boost::serialization::basic_traits,T>, traits_class_version<T>, mpl::int_<0> >::type type; BOOST_STATIC_CONSTANT(int, value = version::type::value); }; Perhaps BOOST_STATIC_CONSTANT isn't working here? I know it seems a bit unlikely. I've tried explicitly instantiating the template and defining the symbol myself but I can't seem to get any of these approaches to work. Why it would work in release mode but not debug is also a mystery to me. Any help appreciated. Thanks, John.
AMDG On 2/16/2011 5:26 AM, John Reid wrote:
Digging a bit deeper in the boost code I found the undefined symbol in boost/serialization/version.hpp:
// default version number is 0. Override with higher version // when class definition changes. template<class T> struct version { template<class U> struct traits_class_version { typedef BOOST_DEDUCED_TYPENAME U::version type; };
typedef mpl::integral_c_tag tag; // note: at least one compiler complained w/o the full qualification // on basic traits below typedef BOOST_DEDUCED_TYPENAME mpl::eval_if< is_base_and_derived<boost::serialization::basic_traits,T>, traits_class_version<T>, mpl::int_<0>
::type type; BOOST_STATIC_CONSTANT(int, value = version::type::value); };
Perhaps BOOST_STATIC_CONSTANT isn't working here?
This is missing something important: #ifndef BOOST_NO_INCLASS_MEMBER_INITIALIZATION template<class T> int version<T>::value; #endif Can you file a trac ticket at http://svn.boost.org/
I know it seems a bit unlikely. I've tried explicitly instantiating the template and defining the symbol myself but I can't seem to get any of these approaches to work. Why it would work in release mode but not debug is also a mystery to me.
Because it's a constant, it must be getting optimized out in release mode. In Christ, Steven Watanabe
On 16/02/11 15:46, Steven Watanabe wrote:
AMDG
On 2/16/2011 5:26 AM, John Reid wrote:
Digging a bit deeper in the boost code I found the undefined symbol in boost/serialization/version.hpp:
// default version number is 0. Override with higher version // when class definition changes. template<class T> struct version { template<class U> struct traits_class_version { typedef BOOST_DEDUCED_TYPENAME U::version type; };
typedef mpl::integral_c_tag tag; // note: at least one compiler complained w/o the full qualification // on basic traits below typedef BOOST_DEDUCED_TYPENAME mpl::eval_if< is_base_and_derived<boost::serialization::basic_traits,T>, traits_class_version<T>, mpl::int_<0>
::type type; BOOST_STATIC_CONSTANT(int, value = version::type::value); };
Perhaps BOOST_STATIC_CONSTANT isn't working here?
This is missing something important:
#ifndef BOOST_NO_INCLASS_MEMBER_INITIALIZATION template<class T> int version<T>::value; #endif
Can you file a trac ticket at http://svn.boost.org/ Have done: https://svn.boost.org/trac/boost/ticket/5196
John.
participants (2)
-
John Reid
-
Steven Watanabe