Boost logo

Boost Users :

Subject: [Boost-users] [serialization] Question about pointers and casting
From: Ben (midfield_at_[hidden])
Date: 2009-10-23 17:42:09


Dear Boost Experts --

I'm using g++ 4.2.1, OS X 10.6.1, boost 1.40, although I have also
seen this on linux. In attempting to
understand how boost::serialization works, I've stumbled across the
following curiosity. The following
program compiles and runs fine (I've eliminated diagnostic output
which verifies the serialization.)

#include <iostream>
#include <fstream>
#include <boost/archive/binary_oarchive.hpp>
#include <boost/archive/binary_iarchive.hpp>

struct A {
  int v;

  template<class Ar>
  void serialize(Ar & ar, const unsigned int ver) {
    ar & v;
  }
};

int
main(int ac, char ** argv) {
  A a; a.v = 10;
  A * a1p = &a;

  const char * fname = "test.bin";
  {
    std::ofstream ofs(fname);
    boost::archive::binary_oarchive ar(ofs);
    ar << a1p;
  }

  A * a2p;

  {
    std::ifstream ifs(fname);
    boost::archive::binary_iarchive ar(ifs);
    ar >> a2p;
  }

  return 0;
}

However, if I add a static_cast<A*> to either a1p or a2p (which are
already declared to be type A*) in
the serialization / deserialization lines, it fails to compile:

#include <iostream>
#include <fstream>
#include <boost/archive/binary_oarchive.hpp>
#include <boost/archive/binary_iarchive.hpp>

struct A {
  int v;

  template<class Ar>
  void serialize(Ar & ar, const unsigned int ver) {
    ar & v;
  }
};

int
main(int ac, char ** argv) {
  A a; a.v = 10;
  A * a1p = &a;

  const char * fname = "test.bin";
  {
    std::ofstream ofs(fname);
    boost::archive::binary_oarchive ar(ofs);
    ar << static_cast<A*>(a1p);
  }

  A * a2p;

  {
    std::ifstream ifs(fname);
    boost::archive::binary_iarchive ar(ifs);
    ar >> static_cast<A*>(a2p);
  }

  return 0;
}

Compilation started at Fri Oct 23 14:31:17

make -k debug
make all "CXX_FLAGS = -g -fno-inline -m64 -I. -I..
-I/opt/local/include -Wall -Wextra -Wpointer-
arith -Wcast-align -Wwrite-strings -Wconversion -Woverloaded-virtual
-Wno-sign-compare -Wno-
unused -fno-nonansi-builtins" \
                 "LD_FLAGS = -g -m64"
g++ -g -fno-inline -m64 -I. -I.. -I/opt/local/include -Wall -Wextra
-Wpointer-arith -Wcast-align -
Wwrite-strings -Wconversion -Woverloaded-virtual -Wno-sign-compare
-Wno-unused -fno-
nonansi-builtins -c test.cc -o test.o
test.cc: In function 'int main(int, char**)':
test.cc:25: error: no match for 'operator<<' in 'ar << a1p'
/opt/local/include/boost/archive/detail/interface_oarchive.hpp:63:
note: candidates are: Archive&
boost::archive::detail::interface_oarchive<Archive>::operator<<(T&)
[with T = A*, Archive =
boost::archive::binary_oarchive]
test.cc:33: error: no match for 'operator>>' in 'ar >> a2p'
/opt/local/include/boost/archive/detail/interface_iarchive.hpp:60:
note: candidates are: Archive&
boost::archive::detail::interface_iarchive<Archive>::operator>>(T&)
[with T = A*, Archive =
boost::archive::binary_iarchive]
make[1]: *** [test.o] Error 1
make[1]: Target `all' not remade because of errors.
make: *** [debug] Error 2

Compilation exited abnormally with code 2 at Fri Oct 23 14:31:18

This completely boggles my mind. My limited understanding suggests
the compiler should not be able
to distinguish between the two programs! I can put the cast on either
one of the two pointers and it
fails, and using an old style cast to A* also fails. I seem to not
understand what boost::serialization is
doing generally, so I was hoping the answer to this question (which is
obviously a theoretical curiosity
and of no practical value) would lead to further insight.

Best regards,
Ben


Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net