[Serialization] this seems wrong

I'm somewhat inexperienced with boost serialization, so forgive me if I'm just missing something. I have a few simple classes that are all serializable. In each class's header, I have BOOST_CLASS_EXPORT( ClassName ) right after the class declaration. All of these classes are header-only, so there is no cpp. All of these classes are very similar, so the statement above is often on the same line of the file (line 21 in this case). When I include all of these headers in a single source file, I get errors like this: 1>Win32WindowImpl.cpp 1>c:\subversion\trunk\vfx\platform\include\messages\minimized.hpp(21) : error C2371: 'vfx::platform::`anonymous-namespace'::boost_serialization_guid_initializer_21' : redefinition; different basic types 1> c:\subversion\trunk\vfx\platform\include\messages\close.hpp(21) : see declaration of 'vfx::platform::`anonymous-namespace'::boost_serialization_guid_initializer_21' 1>c:\subversion\trunk\vfx\platform\include\messages\restored.hpp(21) : error C2371: 'vfx::platform::`anonymous-namespace'::boost_serialization_guid_initializer_21' : redefinition; different basic types 1> c:\subversion\trunk\vfx\platform\include\messages\close.hpp(21) : see declaration of 'vfx::platform::`anonymous-namespace'::boost_serialization_guid_initializer_21' I walked down into the BOOST_CLASS_EXPORT macro and saw that the BOOST_CLASS_EXPORT_GUID macro appends the line number (notice the 21's in the above compiler output) to what it generates. Thinking to myself, "this will never work", I simply went and added empty lines to the header files so that the BOOST_CLASS_EXPORT( ClassName ) was on a different line in each and everything compiled. Am I missing something? Is this fixed in 1.37 (I'm currently forced to use 1.36). If I wanted white-space to matter, I would be writing python :)

Robert Ramey wrote:
Thanks for the quick response and the great library. One solution that comes to mind is to use a combination of file name and line number instead of just the line number via both the __FILE__ and __LINE__ preprocessor directives. Are you aware of any reason why that wouldn't work?

Robert Ramey wrote:
This appears to work and makes more conceptual sense to me as well (sorry if the formatting gets mangled, but you get the idea): replace: #define BOOST_CLASS_EXPORT_GUID(T, K) \ namespace \ { \ ::boost::archive::detail::guid_initializer< T > const & \ BOOST_PP_CAT(boost_serialization_guid_initializer_, __LINE__) \ = ::boost::serialization::singleton< \ ::boost::archive::detail::guid_initializer< T > \ >::get_mutable_instance().export_guid(K); \ } with: #define BOOST_CLASS_EXPORT_GUID(T, K) \ namespace \ { \ ::boost::archive::detail::guid_initializer< T > const & \ BOOST_PP_CAT(boost_serialization_guid_initializer_, T) \ = ::boost::serialization::singleton< \ ::boost::archive::detail::guid_initializer< T > \ >::get_mutable_instance().export_guid(K); \ }

on Wed Nov 26 2008, Kenny Riddile <kfriddile-AT-yahoo.com> wrote:
That will only work if T is a simple identifier or number. A name like std::pair<int,int> would fail. I don't remember offhand whether class template specializations get exported by Boost.Serialization, but it seems to me that this doesn't need to be so hard in any case. You can probably make the namespace-scope variable a static member of a class template and use an explicit instantiation to generate it. If it works, there's no need for an unnamed namespace and no name clashes. -- Dave Abrahams BoostPro Computing http://www.boostpro.com

David Abrahams wrote:
I tried this: template<class T> struct initialize_guid { static guid_initializer< T > const& guid; }; } // namespace detail } // namespace archive } // namespace boost #define BOOST_CLASS_EXPORT_GUID(T, K) \ template<> ::boost::archive::detail::guid_initializer< T > const& \ ::boost::archive::detail::initialize_guid<T>::guid = \ ::boost::serialization::singleton< \ ::boost::archive::detail::guid_initializer< T > \ >::get_mutable_instance().export_guid( K ); but, this only compiles when the macro is used from the global namespace. Otherwise VC++ gives an error similar to: error C2888: 'const boost::archive::detail::guid_initializer<T> &boost::archive::detail::initialize_guid<T>::guid' : symbol cannot be defined within namespace 'messenger' Changing the above code to: template<class T> struct initialize_guid { static guid_initializer< T > const& guid; }; template<class T> guid_initializer< T > const& initialize_guid< T >::guid = ::boost::serialization::singleton< ::boost::archive::detail::guid_initializer< T > >::get_mutable_instance().export_guid( BOOST_PP_STRINGIZE(T) ); } // namespace detail } // namespace archive } // namespace boost #define BOOST_CLASS_EXPORT_GUID(T, K) \ template struct ::boost::archive::detail::initialize_guid<T>; compiles, but breaks the existing public interface (K parameter is being ignored). Anyone have any suggestions?

Kenny Riddile wrote:
I don't know about getting rid of the unnamed namespace but essentially we just need a unique name per type in a translation unit.. so how about: #define BOOST_CLASS_EXPORT_GUID(T, K) \ namespace \ { \ template< typename U > \ class init_guid \ { \ static ::boost::archive::detail::guid_initializer<U> const & \ guid_initializer_; \ }; \ template<> ::boost::archive::detail::guid_initializer<T> const & \ init_guid<T>::guid_initializer_ = \ ::boost::serialization::singleton< \ ::boost::archive::detail::guid_initializer<T> \ >::get_mutable_instance().export_guid(K); \ } -- Michael Marcin

AMDG Michael Marcin wrote:
With a little fiddling, I think that this might be made to work. #define BOOST_CLASS_EXPORT_GUID(T, K) \ namespace \ { \ template< typename U > \ class init_guid; \ template<> \ class init_guid<T> \ { \ static ::boost::archive::detail::guid_initializer<T> const & \ guid_initializer_; \ }; \ ::boost::archive::detail::guid_initializer<T> const & \ init_guid<T>::guid_initializer_ = \ ::boost::serialization::singleton< \ ::boost::archive::detail::guid_initializer<T> \ >::get_mutable_instance().export_guid(K); \ } In Christ, Steven Watanabe

-------------------------------------------------- From: "Kenny Riddile" <kfriddile@yahoo.com> Sent: Wednesday, November 26, 2008 11:33 AM To: <boost@lists.boost.org> Subject: Re: [boost] [Serialization] this seems wrong
Hi :), This is the first thing I thought as well.. I think there might be trouble though if a filename is not constrained to be a valid identifier name. Brandon

Brandon Kohn wrote:
Yes, I had that thought too, especially since I believe __FILE__ gives the entire path of the file. Still, I didn't know if there was some magical way to extract the desired section of the __FILE__ output using boost preprocessor or something. I've never used that library before.

AMDG Kenny Riddile wrote:
There is not. __FILE__ is a character array literal. There is no way to introspect such a beast. Also see http://www.boost.org/doc/html/typeof/refe.html#typeof.incr In Christ, Steven Watanabe
participants (6)
-
Brandon Kohn
-
David Abrahams
-
Kenny Riddile
-
Michael Marcin
-
Robert Ramey
-
Steven Watanabe