Boost logo

Boost :

From: David Abrahams (dave_at_[hidden])
Date: 2005-06-24 08:19:05


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

> David Abrahams wrote:
>> Vladimir Prus <ghost_at_[hidden]> writes:
>>
>
>> I know I'm coming in late here,
>
> Yes you are. the original post was sometime ago and many of the
> issue on this subject were discussed.

I'm sure. I tried to go backward in time, but got lost.

>> but I have always expected that the library worked this way
>> (actually keeping a map of saved object address to archive
>> identifier is a usual arrangement). If it doesn't do that, I'm
>> very surprised. How else do you do tracking?
>
> Of course it works that way. It turns out the the library is
> sufficiently smart to skip tracking (and skip instantiating the code
> for tracking the indicated type) for types which are never
> serialized through pointers. The mechanism for implementing this is
> somewhat unusual

I'm pretty sure I do something similar in Boost.Python, so I can
imagine it. If what you're doing is legal, it has to involve setting
up a function pointer that can be called at runtime to do the
tracking... or else my years of banging my head against similar
problems were in vain...

> and it seems may have caused a mis-apprehension as to what is going
> on here.

...but the means for doing it is completely independent from the
question of whether the behavior is a good idea. :)

>> Also, if tracking a stack object is being made illegal unless it's
>> const, I find that highly surprising, and I see no relationship
>> between its constness and safety due to lifetime issues in this case.
>
> Tracking a stack object makes no sense.

Au contraire; it does. It's easy enough to set up a little graph of
objects on the stack. I'd like to be able to load that back in and
("obviously") get dynamically allocated objects. Why is that
nonsense?

I know a computational physicist who wants to serialize very large
matrices, which are invariably going to be objects on the stack. Why
is that nonsense?

> doing so will result in an archive that cannot be loaded.

I don't know why that should be true.

> Tracking an object whose value can change during the lifetime of an
> archive will also fail when the archive is loaded.

I don't know why that should be true. I can imagine wanting to keep a
"was_serialized" mark on some object. There is often data in an
object that's part of its real logical state w.r.t. the program (and
thus shouldn't be marked mutable), but that shouldn't be serialized.
Why does it matter if that data changes?

I don't understand why the object's value -- other than its internal
pointers and references -- is important to the success of loading an
archive.

> by requiring the << operator to take a const argument when the
> object is of a type that is being tracked, violations of the above
> rules can often be detected at compile time - thereby saving the
> programmer days of work looking for a mistake that will only be
> detected after a failed attempt to load a corrupted archive. (BTW,
> I'm the one that get's the email when this occurs)

Understood. Now you're getting email about the consequences of trying
to prevent it. You can't win ;-)

> Its concievable that there mght be a legitimate case where one wants to
> track an object that is not const during the course of serialization

I'm pretty sure you mean "is not constant." The problem here, or at
least one big problem, is that non-const does not imply non-constant.

> - but no one has presented a credible use case so far.

On the other hand, credible use cases for serializing non-const
objects are common.

> There are cases where the STATIC_ASSERT trips when its not stricly
> necessary but in all of my cases I found it easy to slightly
> restructure the code to avoid the problem. See Joaquin's previous
> post on this subject.

Still looking for the pointer to it.

> In he rare case where one needs to do ar << t where t is not a const
> and it is inconvenient to alter the code to make it so, one has two
> options: Use a const_cast or use the & operator instead of the <<
> operator. Is this such a price to pay to get traps in usage of the
> library that is very likely an error? Is fair that the rest of have
> to forego this facility just so one programmer doesn't have to write
> ar & t instead of ar << t ?

You mean

  ar & my_non_const_object

works? If so, I'm less worried. However, the non-uniformity seems a
bit gratuitous, and I think you're setting a bad precedent by equating
non-const with "will change," even if that interpretation is
overridable.

>> I could easily build a small self-referential structure on the
>> stack that I'd like to send to a archive, and non-constness would
>> be essential in such a scenario. Of course I could create const
>> references to each object and serialize those but why make me jump
>> through hoops?
>
> That's not the case here. you might build it on the stack but it
> would have a type.

? Everything has a type.

> Normally that type would be serialized by something like save(Archve
> &ar, const T & t). From then on T is a const and there is no
> problem and no trap.

No, the problem is that there are other nodes in the structure that t
refers to via non-const reference or pointer.

> The problem comes when you do somethign like
>
> for(...
> X x = ....()
> ar << x
>
> where X is type that maybe tracked. I'm sure you can see the
> problem here if you're trying to track either to recover pointers or
> eliminate duplication.

Yes, I see the problem. But

  for(...
      X const x = ....()
      ar << x

is no less problematic from that point of view.

>> I'm starting to care.
>
> The whole thing has been blown waaay out of proportion.

Maybe. These days, I am putting a lot more attention on small details
of libraries that I hadn't seen much of before. It isn't personal; I
am just trying to keep the overall quality high.

> One little observation. It has come to my attention that const is
> avoided by some programmers due to its tendency to ripple its effect
> throughout the code. Personally I think this is a great mistake and
> the extrat pain in the neck caused by this ripple effect is more
> than compensated by the detection of bugs resulting from side
> effects.

I agree, but AFAICT you're giving const (or lack thereof) a meaning
for which there is no precedent in C++.

-- 
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