Opened 10 years ago

Closed 9 years ago

#7474 closed Bugs (invalid)

compilation error in boost::serialization

Reported by: Like Gao <gao.like@…> Owned by: Robert Ramey
Milestone: To Be Determined Component: serialization
Version: Boost Release Branch Severity: Problem
Keywords: Cc:

Description

Error: passing 'const ... discards qualifiers'

Related File: /opt/local/include/boost/serialization/split_member.hpp

Root cause: In /opt/local/include/boost/serialization/split_member.hpp: calling access::member_save() with a "const & T"

    template<class Archive, class T>
    struct member_saver {
        static void invoke(
            Archive & ar, 
            const T & t,
            const unsigned int file_version
        ){
        	access::member_save(ar, t, file_version);
                                                       ^^ t is "const T&"
        }
    };

But in the called, parameter t is not expecting "const". See file /opt/local/include/boost/serialization/access.hpp:

    // pass calls to users's class implementation
    template<class Archive, class T>
    static void member_save(
        Archive & ar, 
        //const T & t,
        T & t,
        const unsigned int file_version
    ){
        t.save(ar, file_version);
    }

Error trace:

  • Invoking: GCC C++ Compiler
  • g++ -DOS_MACOSX -I/opt/local/gtest/include -I../third_party/leveldb-1.5.0/include -I../third_party/leveldb-1.5.0 -I/opt/local/include -I../src/server/cse -O0 -g3 -Wall -c -fmessage-length=0 -MMD -MP -MF"test/server/cse/bucket_addcells.d" -MT"test/server/cse/bucket_addcells.d" -o "test/server/cse/bucket_addcells.o" "../test/server/cse/bucket_addcells.cpp"
  • /opt/local/include/boost/serialization/access.hpp: In static member function 'static void boost::serialization::access::member_save(Archive&, T&, unsigned int) [with Archive = boost::archive::text_oarchive, T = const cse::SortedBucket<int, float>]':
  • /opt/local/include/boost/serialization/split_member.hpp:43: instantiated from 'static void boost::serialization::detail::member_saver<Archive, T>::invoke(Archive&, const T&, unsigned int) [with Archive = boost::archive::text_oarchive, T = cse::SortedBucket<int, float>]'
  • /opt/local/include/boost/serialization/split_member.hpp:70: instantiated from 'void boost::serialization::split_member(Archive&, T&, unsigned int) [with Archive = boost::archive::text_oarchive, T = cse::SortedBucket<int, float>]'
  • ../src/server/cse/io/sorted.hpp:56: instantiated from 'void cse::SortedBucket<KEY, VAL>::serialize(Archive&, unsigned int) [with Archive = boost::archive::text_oarchive, KEY = int, VAL = float]'
  • /opt/local/include/boost/serialization/access.hpp:118: instantiated from 'static void boost::serialization::access::serialize(Archive&, T&, unsigned int) [with Archive = boost::archive::text_oarchive, T = cse::SortedBucket<int, float>]'
  • /opt/local/include/boost/serialization/serialization.hpp:69: instantiated from 'void boost::serialization::serialize(Archive&, T&, unsigned int) [with Archive = boost::archive::text_oarchive, T = cse::SortedBucket<int, float>]'
  • /opt/local/include/boost/serialization/serialization.hpp:128: instantiated from 'void boost::serialization::serialize_adl(Archive&, T&, unsigned int) [with Archive = boost::archive::text_oarchive, T = cse::SortedBucket<int, float>]'
  • /opt/local/include/boost/archive/detail/oserializer.hpp:148: instantiated from 'void boost::archive::detail::oserializer<Archive, T>::save_object_data(boost::archive::detail::basic_oarchive&, const void*) const [with Archive = boost::archive::text_oarchive, T = cse::SortedBucket<int, float>]' ../test/server/cse/bucket_addcells.cpp:63: instantiated from here
  • /opt/local/include/boost/serialization/access.hpp:93: error: passing 'const cse::SortedBucket<int, float>' as 'this' argument of 'void cse::SortedBucket<KEY, VAL>::save(Archive&, unsigned int) [with Archive = boost::archive::text_oarchive, KEY = int, VAL = float]' discards qualifiers

Change History (5)

comment:1 by Robert Ramey, 10 years ago

Resolution: invalid
Status: newclosed

I'm guessing that the client code does something like

myclass x;

text_oarchive oa(...

oa << x; error - x must be const !!!

There is a long explanation in the rationale section of the manual which explains why this is so.

Of course, without the rest of the program I can't verify whether my presumption is right or wrong about this. But for now, I'm going to assume I'm corrected and close this ticket.

Robert Ramey

comment:2 by Like Gao <gao.like@…>, 10 years ago

Resolution: invalid
Status: closedreopened

Hi, I report this bug as it can be produced in below code --- where it doesn't matter if we use "const" Class in the client code or not. Thanks, -Like

//============================================================================
// Name        : boost_bug.cpp
// Author      : 
// Version     :
// Copyright   : Your copyright notice
//============================================================================

#include <iostream>
#include <tr1/memory>
#include <fstream>
#include <iostream>
#include <iostream>
#include <boost/archive/text_oarchive.hpp>


class MyClassA
{
public:
	MyClassA(int x):xx(x){};
	int xx;
private:

	friend class boost::serialization::access;

	template<class Archive>
	void save(Archive & ar, const unsigned int version) {
		//ar << xx;
	}

	template<class Archive>
	void load(Archive & ar, const unsigned int version) {
		//ar >> xx;
	}

	BOOST_SERIALIZATION_SPLIT_MEMBER();
};




int main() {
	 MyClassA clsA(12);
	std::ofstream f("/tmp/boost_clsA", std::ios::binary);
	if (f.fail()) return -1;
	boost::archive::text_oarchive oa(f);
	oa << clsA;
	f.close();
	return 0;
}

comment:3 by Robert Ramey, 10 years ago

Resolution: invalid
Status: reopenedclosed
int main() {
	const MyClassA clsA(12); // error - should be "const"
	std::ofstream f("/tmp/boost_clsA", std::ios::binary);
	if (f.fail()) return -1;
	boost::archive::text_oarchive oa(f);
	oa << clsA;
	f.close();
	return 0;
}

Exactly as I expected. For this to compile you have to have the "const".

The reason for this is explained in the Rationale section in the documentation. Please read it.

Robert Ramey

comment:4 by Like Gao <gao.like@…>, 10 years ago

Resolution: invalid
Status: closedreopened

I have to report this again. Changing to const form also gave the exact same error:

const MyClassA clsA(12); // error - should be "const"

Please try this example with const form. I don't know if this work with VC but gcc always gave error even the const form.

As in my first post, the issue appears due to the one line change in /opt/local/include/boost/serialization/access.hpp:

    // pass calls to users's class implementation
    template<class Archive, class T>
    static void member_save(
        Archive & ar, 
        //const T & t,   // change to below
        T & t,
        const unsigned int file_version
    ){
        t.save(ar, file_version);
    }

comment:5 by Robert Ramey, 9 years ago

Resolution: invalid
Status: reopenedclosed

The following compiles for me w/o problem.

Note that I made one change - I added "const" to the save member function.

//============================================================================
// Name        : boost_bug.cpp
// Author      : 
// Version     :
// Copyright   : Your copyright notice
//============================================================================

#include <iostream>
#include <fstream>
#include <iostream>
#include <iostream>
#include <boost/archive/text_oarchive.hpp>

class MyClassA
{
public:
	MyClassA(int x):xx(x){};
	int xx;
private:

	friend class boost::serialization::access;

	template<class Archive>
	void save(Archive & ar, const unsigned int version) const {
		//ar << xx;
	}

	template<class Archive>
	void load(Archive & ar, const unsigned int version) {
		//ar >> xx;
	}

	BOOST_SERIALIZATION_SPLIT_MEMBER();
};

int main() {
	 MyClassA clsA(12);
	std::ofstream f("/tmp/boost_clsA", std::ios::binary);
	if (f.fail()) return -1;
	boost::archive::text_oarchive oa(f);
	oa << clsA;
	f.close();
	return 0;
}
Note: See TracTickets for help on using tickets.