Boost logo

Boost :

From: David Abrahams (dave_at_[hidden])
Date: 2005-09-12 16:06:33


"Robert Ramey" <ramey_at_[hidden]> writes:

> Honestly, with time I have available, I've been resolving a couple of
> obscure but problematic issues re RC_1_33_0.
>
> Just to summarize:
>
> a) I've agreed to enhance the tutorial section on pointers so that the
> application of serialization of derived pointers isn't overlooked by the
> casual reader.
>
> b) I've agreed to alter the "Archive Concept" section
> i) to eliminate the implementation of of the functions.
> ii) to put it in a tabular format without the "class ... "
> iii) consider whether it would better or worse to make to almost
> identical sections for loading archives and saving archives or just one
> section with notes for the operators/functions which don't apply.

If they have commonalities it may make sense to make them both
refinements of the same base concept, "Archive." That's how you
factor out commonality in concept definitions. It also makes a lot of
sense because of your universal "&" operator, so users can write the
requirements on their serialize() functions.

> iv) probably change the name from "Archive Concept" to "Archive Type".
> I still have reservations about this as the term Archive is used to refer to
> any type that supports a specified set of operations. That would seem to
> fit in the definition of a concept to me. I'm still mulling this over.

i-iii sound perfectly appropriate for a concept definition. In that
light, I don't know why you'd want to do iv; it seems completely
incongruous. The fact that iv appears in your list with the label
"probably" makes me wonder if you have understood me. Let me
summarize my position:

  * We need Input and Output Archive concept definitions: sets of
    requirements that a type needs need to fulfill in order to use it
    as an archive with the serialization library.

  * These concept definitions are properly grouped with the
    serialization library.

  * You should find some way to describe what it means for an input
    and an output archive to be compatible. Try to do that as
    formally as possible. You may have to rely on the fuzzy C++
    notion of "equivalence," but I wouldn't blame you for that.

  * If you want to describe the implementation and/or interface
    specifics of the library-supplied archives (not a bad idea), that
    should not be labelled a "concept."

> c) Re the last issue of which namespace non-instrusive serialization
> functions should be placed into.
>
> I actually did spend a lot of time on this in the past. The issue
> surfaced when I first compiled with CW, gcc 4.0 and Commeau.

CW does 2-phase lookup properly, I believe.

> I carefully studied the explanation in Vandevoordes and Jostuttis
> book, and made changes. This resulted in a much simpler
> "suggestion" as which namespace to use for non-intrusive
> serialization functions. It also resulted in all the above
> compilers compiling and executing all the tests without problem of
> any kind when.
>
> > So I've already spent a lot of time on this issue.

Unfortunately, it's easy to write a test that fails to uncover a
problem. The optimal thing to do when you are confronted with an
issue like this is to write tests that try to use the issue to break
your library. If you pick the wrong declaration order or
inadvertently associate the wrong namespaces, you'll miss it.

> Now it seems I didn't appreciate all there is two know about
> two-phase lookup. So it takes some time to go back and review all
> the considerations that entered my mind when I "fixed" it the first
> time. It's not that I'm dismissing your concerns.

good.

> Remind me of what its that you want to see changed. The
> documentation re-worded or what? If its just a question about
> making that documentation more precise, that would be pretty easy.

Precision isn't the issue. It's hard to imagine that this helps,
since you can look at the message history as easily as I can, but let
me refresh your memory:

  4. The documentation says that you can write your freestanding
     serialize() function in namespace boost::serialization, with the
     strong implication that it will work even on compilers that
     support ADL. But it won't work unless boost::serialization is an
     associated namespace of one of the arguments, as demonstrated by
     the following program:

          namespace me
          {
            class X {};
          }

          namespace boost { namespace serialization
          {

            template <class T>
            int call_serialize(T const& x)
            {
               serialize(x);
               return 0;
            }

            void serialize(me::X);

          }}

          int y = boost::serialization::call_serialize(me::X());

     As far as I can tell, there's no requirement that any of the
     arguments to serialize have boost::serialization as an associated
     namespace.

> If one's compiler supports ADL, then he can use a free function in
> namespaces associated with the type being serialized. But it's not
> a requirement

  I beg to differ. And the docs make it sound as though putting the
  functions in boost::serialization is the more portable of the two
  options.

So the recommendation that users write their freestanding serialize
functions in namespace boost::serialization doesn't work in general on
conforming compilers, and yet your documentation makes it should like
it's the most portable approach. You need to mke sure that it isn't
made out to be a portable option. The best thing you could do, IMO,
is write a recommendation that works on conforming compilers, e.g.

  Overload serialize in the namespace of your class.

Then write another, possibly uglier, recommendation that works on all
supported compilers. If you have to use macros, that's fine. E.g.,

  // somewhere in the serialization library
  #if BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP
  # define BOOST_SERIALIZE(namespace) serialize
  #else
  # define BOOST_SERIALIZE(namespace) namespace::serialize
  #endif

  // user code
  namespace my { namespace ns
  {
    class my_class { ... };

    template <class A>
    void serialize(A&, my_class); // declaration (unused in non-ADL case)
  }}

  // definition
  template <class Archive>
  void BOOST_SERIALIZE(my::ns)(Archive& ar, ny::ns::my_class& x)
  {
     ...
  }

-- 
Dave Abrahams
Boost Consulting
www.boost-consulting.com

Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk