title: Do I need to make a type a POD to persist it with a memory-mapped file?
body: <p>Pointers cannot be persisted directly to file, because they point to absolute addresses. To address this issue I wrote a <code>relative_ptr</code> template that holds an offset instead of an absolute address.</p>
  
  <p>Based on the fact that only trivially copyable types can be safely copied bit-by-bit, I made the assumption that this type needed to be trivially copyable to be safely persisted in a memory-mapped file and retrieved later on.</p>
  
  <p>This restriction turned out to be a bit problematic, because the compiler generated copy constructor does not behave in a meaningful way. I found nothing that forbid me from defaulting the copy constructor and making it private, so I made it private to avoid accidental copies that would lead to undefined behaviour.</p>
  
  <p>Later on, I found <a href="http://www.boost.org/doc/libs/1_47_0/doc/html/interprocess/offset_ptr.html"><code>boost::interprocess::offset_ptr</code></a> whose creation was driven by the same needs. However, it turns out that <code>offset_ptr</code> is not trivially copyable because it implements its own custom copy constructor.</p>
  
  <p>Is my assumption that the smart pointer needs to be trivially copyable to be persisted safely wrong?</p>
  
  <p>If there's no such restriction, I wonder if I can safely do the following as well. If not, exactly what are the requirements a type must fulfill to be usable in the scenario I described above?</p>
  
  <pre><code>struct base {
      int x;
      virtual void f() = 0;
      virtual ~base() {} // virtual members!
  };
  
  struct derived : virtual base {
      int x;
      void f() { std::cout &lt;&lt; x; }
  };
  
  using namespace boost::interprocess;
  
  void persist() {
      file_mapping file("blah");
      mapped_region region(file, read_write, 128, sizeof(derived));
      // create object on a memory-mapped file
      derived* d = new (region.get_address()) derived();
      d.x = 42;
      d-&gt;f();
      region.flush();
  }
  
  void retrieve() {
      file_mapping file("blah");
      mapped_region region(file, read_write, 128, sizeof(derived));
      derived* d = region.get_address();
      d-&gt;f();
  }
  
  int main() {
      persist();
      retrieve();
  }
  </code></pre>
  
  <hr>
  
  <p>Thanks to all those that provided alternatives. It's unlikely that I will be using something else any time soon, because as I explained, I already have a working solution. And as you can see from the use of question marks above, I'm really interested in knowing why Boost can get away without a trivially copyable type, and how far can you go with it: it's quite obvious that classes with virtual members will not work, but <strong>where do you draw the line?</strong></p>