Opened 14 years ago

Closed 13 years ago

#2180 closed Bugs (fixed)

Errors on binary serialization of vector

Reported by: k_karanikolas@… Owned by: Matthias Troyer
Milestone: To Be Determined Component: serialization
Version: Boost 1.35.0 Severity: Problem
Keywords: Cc:

Description

I am encountering compiler errors when trying to serialize objects stored in a vector, using boost 1.35, as well as boost svn.

Here's a simplified test case

#include <fstream>
#include <vector>
#include <boost/archive/binary_oarchive.hpp>
#include <boost/archive/text_oarchive.hpp>
#include <boost/serialization/vector.hpp>
void test()
{
	std::vector<int> vec;	
	std::ofstream ofs("file");

	// boost::archive::text_oarchive oarc(ofs); // Compiles fine under both GCC 4.0.1 and GCC 4.1
	boost::archive::binary_oarchive oarc(ofs); // Compiles under GCC 4.0.1 but not GCC 4.1. Also compiles fine with boost 1.34/GCC 4.1
	
	oarc & vec;
}

Whereas serializing to a text archive works fine under both compilers, binary serialization triggers compiler errors under GCC 4.1


/Users/kostas/develop/ext/boost/boost/mpl/aux_/preprocessed/gcc/template_arity.hpp: In instantiation of ‘const int boost::mpl::aux::template_arity_impl<boost::archive::basic_binary_oprimitive<boost::archive::binary_oarchive, char, std::char_traits<char> >::use_array_optimization, 3>::value’:
/Users/kostas/develop/ext/boost/boost/mpl/aux_/preprocessed/gcc/template_arity.hpp:93:   instantiated from ‘const int boost::mpl::aux::template_arity<boost::archive::basic_binary_oprimitive<boost::archive::binary_oarchive, char, std::char_traits<char> >::use_array_optimization>::value’
/Users/kostas/develop/ext/boost/boost/mpl/aux_/preprocessed/gcc/template_arity.hpp:98:   instantiated from ‘boost::mpl::aux::template_arity<boost::archive::basic_binary_oprimitive<boost::archive::binary_oarchive, char, std::char_traits<char> >::use_array_optimization>’
/Users/kostas/develop/ext/boost/boost/mpl/aux_/preprocessed/gcc/apply.hpp:48:   instantiated from ‘boost::mpl::apply1<boost::archive::basic_binary_oprimitive<boost::archive::binary_oarchive, char, std::char_traits<char> >::use_array_optimization, int>’
/Users/kostas/develop/ext/boost/boost/archive/binary_oarchive.hpp:53:   instantiated from ‘boost::serialization::use_array_optimization<boost::archive::binary_oarchive>::apply<int>’
/Users/kostas/develop/ext/boost/boost/serialization/vector.hpp:119:   instantiated from ‘void boost::serialization::save(Archive&, const std::vector<U, Allocator>&, unsigned int) [with Archive = boost::archive::binary_oarchive, U = int, Allocator = std::allocator<int>]’
/Users/kostas/develop/ext/boost/boost/serialization/split_free.hpp:45:   instantiated from ‘static void boost::serialization::free_saver<Archive, T>::invoke(Archive&, const T&, unsigned int) [with Archive = boost::archive::binary_oarchive, T = std::vector<int, std::allocator<int> >]’
/Users/kostas/develop/ext/boost/boost/serialization/split_free.hpp:74:   instantiated from ‘void boost::serialization::split_free(Archive&, T&, unsigned int) [with Archive = boost::archive::binary_oarchive, T = std::vector<int, std::allocator<int> >]’
/Users/kostas/develop/ext/boost/boost/serialization/vector.hpp:139:   instantiated from ‘void boost::serialization::serialize(Archive&, std::vector<U, Allocator>&, unsigned int) [with Archive = boost::archive::binary_oarchive, U = int, Allocator = std::allocator<int>]’
/Users/kostas/develop/ext/boost/boost/serialization/serialization.hpp:133:   instantiated from ‘void boost::serialization::serialize_adl(Archive&, T&, unsigned int) [with Archive = boost::archive::binary_oarchive, T = std::vector<int, std::allocator<int> >]’
/Users/kostas/develop/ext/boost/boost/archive/detail/oserializer.hpp:144:   instantiated from ‘void boost::archive::detail::oserializer<Archive, T>::save_object_data(boost::archive::detail::basic_oarchive&, const void*) const [with Archive = boost::archive::binary_oarchive, T = std::vector<int, std::allocator<int> >]’
test3.cpp:15:   instantiated from here
/Users/kostas/develop/ext/boost/boost/mpl/aux_/preprocessed/gcc/template_arity.hpp:85: error: call of overloaded ‘arity_helper(boost::mpl::aux::type_wrapper<boost::archive::basic_binary_oprimitive<boost::archive::binary_oarchive, char, std::char_traits<char> >::use_array_optimization>, boost::mpl::aux::arity_tag<3>)’ is ambiguous
/Users/kostas/develop/ext/boost/boost/mpl/aux_/preprocessed/gcc/template_arity.hpp:30: note: candidates are: char (& boost::mpl::aux::arity_helper(...))[1]
/Users/kostas/develop/ext/boost/boost/mpl/aux_/preprocessed/gcc/template_arity.hpp:51: note:                 char (& boost::mpl::aux::arity_helper(boost::mpl::aux::type_wrapper<F<T1, T2, T3> >, boost::mpl::aux::arity_tag<3>))[4] [with F = boost::archive::basic_binary_oprimitive<Archive, Elem, Tr>::use_array_optimization, T1 = boost::archive::binary_oarchive, T2 = char, T3 = std::char_traits<char>]
/Users/kostas/develop/ext/boost/boost/mpl/aux_/preprocessed/gcc/template_arity.hpp:51: note:                 char (& boost::mpl::aux::arity_helper(boost::mpl::aux::type_wrapper<F<T1, T2, T3> >, boost::mpl::aux::arity_tag<3>))[4] [with F = boost::archive::basic_binary_oprimitive<Archive, Elem, Tr>::use_array_optimization, T1 = boost::archive::binary_oarchive, T2 = char, T3 = std::char_traits<char>]
/Users/kostas/develop/ext/boost/boost/mpl/aux_/preprocessed/gcc/template_arity.hpp: In instantiation of ‘const int boost::mpl::aux::template_arity<boost::archive::basic_binary_oprimitive<boost::archive::binary_oarchive, char, std::char_traits<char> >::use_array_optimization>::value’:
/Users/kostas/develop/ext/boost/boost/mpl/aux_/preprocessed/gcc/template_arity.hpp:98:   instantiated from ‘boost::mpl::aux::template_arity<boost::archive::basic_binary_oprimitive<boost::archive::binary_oarchive, char, std::char_traits<char> >::use_array_optimization>’
/Users/kostas/develop/ext/boost/boost/mpl/aux_/preprocessed/gcc/apply.hpp:48:   instantiated from ‘boost::mpl::apply1<boost::archive::basic_binary_oprimitive<boost::archive::binary_oarchive, char, std::char_traits<char> >::use_array_optimization, int>’
/Users/kostas/develop/ext/boost/boost/archive/binary_oarchive.hpp:53:   instantiated from ‘boost::serialization::use_array_optimization<boost::archive::binary_oarchive>::apply<int>’
/Users/kostas/develop/ext/boost/boost/serialization/vector.hpp:119:   instantiated from ‘void boost::serialization::save(Archive&, const std::vector<U, Allocator>&, unsigned int) [with Archive = boost::archive::binary_oarchive, U = int, Allocator = std::allocator<int>]’
/Users/kostas/develop/ext/boost/boost/serialization/split_free.hpp:45:   instantiated from ‘static void boost::serialization::free_saver<Archive, T>::invoke(Archive&, const T&, unsigned int) [with Archive = boost::archive::binary_oarchive, T = std::vector<int, std::allocator<int> >]’
/Users/kostas/develop/ext/boost/boost/serialization/split_free.hpp:74:   instantiated from ‘void boost::serialization::split_free(Archive&, T&, unsigned int) [with Archive = boost::archive::binary_oarchive, T = std::vector<int, std::allocator<int> >]’
/Users/kostas/develop/ext/boost/boost/serialization/vector.hpp:139:   instantiated from ‘void boost::serialization::serialize(Archive&, std::vector<U, Allocator>&, unsigned int) [with Archive = boost::archive::binary_oarchive, U = int, Allocator = std::allocator<int>]’
/Users/kostas/develop/ext/boost/boost/serialization/serialization.hpp:133:   instantiated from ‘void boost::serialization::serialize_adl(Archive&, T&, unsigned int) [with Archive = boost::archive::binary_oarchive, T = std::vector<int, std::allocator<int> >]’
/Users/kostas/develop/ext/boost/boost/archive/detail/oserializer.hpp:144:   instantiated from ‘void boost::archive::detail::oserializer<Archive, T>::save_object_data(boost::archive::detail::basic_oarchive&, const void*) const [with Archive = boost::archive::binary_oarchive, T = std::vector<int, std::allocator<int> >]’
test3.cpp:15:   instantiated from here
/Users/kostas/develop/ext/boost/boost/mpl/aux_/preprocessed/gcc/template_arity.hpp:93: error: ‘<expression error>’ is not a valid template argument for type ‘int’ because it is a non-constant expression
/Users/kostas/develop/ext/boost/boost/mpl/aux_/preprocessed/gcc/template_arity.hpp: In instantiation of ‘boost::mpl::aux::template_arity<boost::archive::basic_binary_oprimitive<boost::archive::binary_oarchive, char, std::char_traits<char> >::use_array_optimization>’:
/Users/kostas/develop/ext/boost/boost/mpl/aux_/preprocessed/gcc/apply.hpp:48:   instantiated from ‘boost::mpl::apply1<boost::archive::basic_binary_oprimitive<boost::archive::binary_oarchive, char, std::char_traits<char> >::use_array_optimization, int>’
/Users/kostas/develop/ext/boost/boost/archive/binary_oarchive.hpp:53:   instantiated from ‘boost::serialization::use_array_optimization<boost::archive::binary_oarchive>::apply<int>’
/Users/kostas/develop/ext/boost/boost/serialization/vector.hpp:119:   instantiated from ‘void boost::serialization::save(Archive&, const std::vector<U, Allocator>&, unsigned int) [with Archive = boost::archive::binary_oarchive, U = int, Allocator = std::allocator<int>]’
/Users/kostas/develop/ext/boost/boost/serialization/split_free.hpp:45:   instantiated from ‘static void boost::serialization::free_saver<Archive, T>::invoke(Archive&, const T&, unsigned int) [with Archive = boost::archive::binary_oarchive, T = std::vector<int, std::allocator<int> >]’
/Users/kostas/develop/ext/boost/boost/serialization/split_free.hpp:74:   instantiated from ‘void boost::serialization::split_free(Archive&, T&, unsigned int) [with Archive = boost::archive::binary_oarchive, T = std::vector<int, std::allocator<int> >]’
/Users/kostas/develop/ext/boost/boost/serialization/vector.hpp:139:   instantiated from ‘void boost::serialization::serialize(Archive&, std::vector<U, Allocator>&, unsigned int) [with Archive = boost::archive::binary_oarchive, U = int, Allocator = std::allocator<int>]’
/Users/kostas/develop/ext/boost/boost/serialization/serialization.hpp:133:   instantiated from ‘void boost::serialization::serialize_adl(Archive&, T&, unsigned int) [with Archive = boost::archive::binary_oarchive, T = std::vector<int, std::allocator<int> >]’
/Users/kostas/develop/ext/boost/boost/archive/detail/oserializer.hpp:144:   instantiated from ‘void boost::archive::detail::oserializer<Archive, T>::save_object_data(boost::archive::detail::basic_oarchive&, const void*) const [with Archive = boost::archive::binary_oarchive, T = std::vector<int, std::allocator<int> >]’
test3.cpp:15:   instantiated from here
/Users/kostas/develop/ext/boost/boost/mpl/aux_/preprocessed/gcc/template_arity.hpp:98: error: ‘<expression error>’ is not a valid template argument for type ‘int’ because it is a non-constant expression
/Users/kostas/develop/ext/boost/boost/mpl/aux_/preprocessed/gcc/apply.hpp: In instantiation of ‘boost::mpl::apply1<boost::archive::basic_binary_oprimitive<boost::archive::binary_oarchive, char, std::char_traits<char> >::use_array_optimization, int>’:
/Users/kostas/develop/ext/boost/boost/archive/binary_oarchive.hpp:53:   instantiated from ‘boost::serialization::use_array_optimization<boost::archive::binary_oarchive>::apply<int>’
/Users/kostas/develop/ext/boost/boost/serialization/vector.hpp:119:   instantiated from ‘void boost::serialization::save(Archive&, const std::vector<U, Allocator>&, unsigned int) [with Archive = boost::archive::binary_oarchive, U = int, Allocator = std::allocator<int>]’
/Users/kostas/develop/ext/boost/boost/serialization/split_free.hpp:45:   instantiated from ‘static void boost::serialization::free_saver<Archive, T>::invoke(Archive&, const T&, unsigned int) [with Archive = boost::archive::binary_oarchive, T = std::vector<int, std::allocator<int> >]’
/Users/kostas/develop/ext/boost/boost/serialization/split_free.hpp:74:   instantiated from ‘void boost::serialization::split_free(Archive&, T&, unsigned int) [with Archive = boost::archive::binary_oarchive, T = std::vector<int, std::allocator<int> >]’
/Users/kostas/develop/ext/boost/boost/serialization/vector.hpp:139:   instantiated from ‘void boost::serialization::serialize(Archive&, std::vector<U, Allocator>&, unsigned int) [with Archive = boost::archive::binary_oarchive, U = int, Allocator = std::allocator<int>]’
/Users/kostas/develop/ext/boost/boost/serialization/serialization.hpp:133:   instantiated from ‘void boost::serialization::serialize_adl(Archive&, T&, unsigned int) [with Archive = boost::archive::binary_oarchive, T = std::vector<int, std::allocator<int> >]’
/Users/kostas/develop/ext/boost/boost/archive/detail/oserializer.hpp:144:   instantiated from ‘void boost::archive::detail::oserializer<Archive, T>::save_object_data(boost::archive::detail::basic_oarchive&, const void*) const [with Archive = boost::archive::binary_oarchive, T = std::vector<int, std::allocator<int> >]’
test3.cpp:15:   instantiated from here
/Users/kostas/develop/ext/boost/boost/mpl/aux_/preprocessed/gcc/apply.hpp:48: error: ‘<expression error>’ is not a valid template argument for type ‘int’ because it is a non-constant expression
/Users/kostas/develop/ext/boost/boost/archive/binary_oarchive.hpp: In instantiation of ‘boost::serialization::use_array_optimization<boost::archive::binary_oarchive>::apply<int>’:
/Users/kostas/develop/ext/boost/boost/serialization/vector.hpp:119:   instantiated from ‘void boost::serialization::save(Archive&, const std::vector<U, Allocator>&, unsigned int) [with Archive = boost::archive::binary_oarchive, U = int, Allocator = std::allocator<int>]’
/Users/kostas/develop/ext/boost/boost/serialization/split_free.hpp:45:   instantiated from ‘static void boost::serialization::free_saver<Archive, T>::invoke(Archive&, const T&, unsigned int) [with Archive = boost::archive::binary_oarchive, T = std::vector<int, std::allocator<int> >]’
/Users/kostas/develop/ext/boost/boost/serialization/split_free.hpp:74:   instantiated from ‘void boost::serialization::split_free(Archive&, T&, unsigned int) [with Archive = boost::archive::binary_oarchive, T = std::vector<int, std::allocator<int> >]’
/Users/kostas/develop/ext/boost/boost/serialization/vector.hpp:139:   instantiated from ‘void boost::serialization::serialize(Archive&, std::vector<U, Allocator>&, unsigned int) [with Archive = boost::archive::binary_oarchive, U = int, Allocator = std::allocator<int>]’
/Users/kostas/develop/ext/boost/boost/serialization/serialization.hpp:133:   instantiated from ‘void boost::serialization::serialize_adl(Archive&, T&, unsigned int) [with Archive = boost::archive::binary_oarchive, T = std::vector<int, std::allocator<int> >]’
/Users/kostas/develop/ext/boost/boost/archive/detail/oserializer.hpp:144:   instantiated from ‘void boost::archive::detail::oserializer<Archive, T>::save_object_data(boost::archive::detail::basic_oarchive&, const void*) const [with Archive = boost::archive::binary_oarchive, T = std::vector<int, std::allocator<int> >]’
test3.cpp:15:   instantiated from here
/Users/kostas/develop/ext/boost/boost/archive/binary_oarchive.hpp:53: error: no type named ‘type’ in ‘struct boost::mpl::apply1<boost::archive::basic_binary_oprimitive<boost::archive::binary_oarchive, char, std::char_traits<char> >::use_array_optimization, int>’
/Users/kostas/develop/ext/boost/boost/serialization/vector.hpp: In function ‘void boost::serialization::save(Archive&, const std::vector<U, Allocator>&, unsigned int) [with Archive = boost::archive::binary_oarchive, U = int, Allocator = std::allocator<int>]’:
/Users/kostas/develop/ext/boost/boost/serialization/split_free.hpp:45:   instantiated from ‘static void boost::serialization::free_saver<Archive, T>::invoke(Archive&, const T&, unsigned int) [with Archive = boost::archive::binary_oarchive, T = std::vector<int, std::allocator<int> >]’
/Users/kostas/develop/ext/boost/boost/serialization/split_free.hpp:74:   instantiated from ‘void boost::serialization::split_free(Archive&, T&, unsigned int) [with Archive = boost::archive::binary_oarchive, T = std::vector<int, std::allocator<int> >]’
/Users/kostas/develop/ext/boost/boost/serialization/vector.hpp:139:   instantiated from ‘void boost::serialization::serialize(Archive&, std::vector<U, Allocator>&, unsigned int) [with Archive = boost::archive::binary_oarchive, U = int, Allocator = std::allocator<int>]’
/Users/kostas/develop/ext/boost/boost/serialization/serialization.hpp:133:   instantiated from ‘void boost::serialization::serialize_adl(Archive&, T&, unsigned int) [with Archive = boost::archive::binary_oarchive, T = std::vector<int, std::allocator<int> >]’
/Users/kostas/develop/ext/boost/boost/archive/detail/oserializer.hpp:144:   instantiated from ‘void boost::archive::detail::oserializer<Archive, T>::save_object_data(boost::archive::detail::basic_oarchive&, const void*) const [with Archive = boost::archive::binary_oarchive, T = std::vector<int, std::allocator<int> >]’
test3.cpp:15:   instantiated from here
/Users/kostas/develop/ext/boost/boost/serialization/vector.hpp:119: error: no type named ‘type’ in ‘struct boost::serialization::use_array_optimization<boost::archive::binary_oarchive>::apply<int>’

My compiler versions are

Using built-in specs.
Target: powerpc-apple-darwin9
Configured with: /var/tmp/gcc/gcc-5465~16/src/configure --disable-checking -enable-werror --prefix=/usr --mandir=/share/man --enable-languages=c,objc,c++,obj-c++ --program-transform-name=/^[cg][^.-]*$/s/$/-4.0/ --with-gxx-include-dir=/include/c++/4.0.0 --with-slibdir=/usr/lib --build=i686-apple-darwin9 --program-prefix= --host=powerpc-apple-darwin9 --target=powerpc-apple-darwin9
Thread model: posix
gcc version 4.0.1 (Apple Inc. build 5465)
Using built-in specs.
Target: psp
Configured with: ../configure --prefix=/Users/kostas/develop/psp/pspdev --target=psp --enable-languages=c,c++ --with-newlib --enable-cxx-flags=-G0
Thread model: single
gcc version 4.1.0 (PSPDEV 20060507)

Thanks in advance

Change History (8)

comment:1 by Robert Ramey, 14 years ago

Owner: changed from Robert Ramey to Matthias Troyer

Mathias,

Could you take a look at this for me please?

Robert Ramey

comment:2 by anonymous, 14 years ago

I will have to install gcc 4.1 It works for me using gcc 4.0 and gcc 4.2

comment:3 by k_karanikolas@…, 14 years ago

I investigated a little bit further which version triggers the error, and it appears to be 4.1.0.

I compiled a stock gcc-4.1.0, and the error is still there.

Using built-in specs.
Target: i686-pc-linux-gnu
Configured with: ../configure --prefix=/home/kostas/local/ --enable-languages=c,c++
Thread model: posix
gcc version 4.1.0

Ubuntu's gcc-4.1.3 however, does not trigger this error

Using built-in specs.
Target: i486-linux-gnu
Configured with: ../src/configure -v --enable-languages=c,c++,fortran,objc,obj-c++,treelang --prefix=/usr --enable-shared --with-system-zlib --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --enable-nls --with-gxx-include-dir=/usr/include/c++/4.1.3 --program-suffix=-4.1 --enable-__cxa_atexit --enable-clocale=gnu --enable-libstdcxx-debug --enable-mpfr --enable-checking=release i486-linux-gnu
Thread model: posix
gcc version 4.1.3 20080308 (prerelease) (Ubuntu 4.1.2-21ubuntu1)

Unfortunately, I am using 4.1.0 not by choice, but because the community supported compiler/toolset for my target platform (PSP) is based on stock gcc-4.1.0 plus some back-end patches. I'll try to apply the patches to the latest of the 4.1 line and see if the problem is still there. At any rate I think this issue can potentially "bite" someone using 4.1.0.

Also in the mailing list archives, (http://lists.boost.org/boost-users/2008/07/38112.php) I've found something that resembles the errors I'm getting. So it maybe possible to construct a workaround to what appears to be a compiler bug.

Thanks again,

Kostas

comment:4 by k_karanikolas@…, 14 years ago

One more update. I was able to update my toolchain to 4.1.2 and the previously mentioned errors have gone. It appears that there is some kind of compiler bug in gcc in version 4.1.0. At any rate you may want to close this issue, but perhaps add some kind of warning in the documentation, to help people that may encounter similar problems.

Thanks Kostas

comment:5 by Matthias Troyer, 14 years ago

We can turn array optimizations off for 4.1.0. That way it will still compile, however at the cost of substantially decreased performance. Would you prefer that over compiler errors due to compiler bugs?

in reply to:  5 comment:6 by k_karanikolas@…, 14 years ago

I think it might be better to opt for compatibility rather than performance. Perhaps even controlling the inclusion of these optimizations through a #define. This way it may make it easier for people to diagnose such a problems which may exist in other compiler versions.

comment:7 by Matthias Troyer, 13 years ago

The offending code has been rewritten some time ago. Can someone with access to the involved compilers please try if this is still an issue?

comment:8 by anonymous, 13 years ago

Resolution: fixed
Status: newclosed

I'm closing this since I believe that this issue should not occur with the current code.

Note: See TracTickets for help on using tickets.