Opened 10 years ago
Closed 9 years ago
#7474 closed Bugs (invalid)
compilation error in boost::serialization
| Reported by: | 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 , 10 years ago
| Resolution: | → invalid |
|---|---|
| Status: | new → closed |
comment:2 by , 10 years ago
| Resolution: | invalid |
|---|---|
| Status: | closed → reopened |
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 , 10 years ago
| Resolution: | → invalid |
|---|---|
| Status: | reopened → closed |
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 , 10 years ago
| Resolution: | invalid |
|---|---|
| Status: | closed → reopened |
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 , 9 years ago
| Resolution: | → invalid |
|---|---|
| Status: | reopened → closed |
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;
}

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