Boost logo

Boost Users :

From: troy d. straszheim (troy_at_[hidden])
Date: 2005-11-14 05:29:07


On Sun, Nov 13, 2005 at 04:02:27PM -0800, Robert Ramey wrote:
> >> uninitialized bools.
> >> floating/double NaN, +/- inf, etc.
> >>
> >
> > We hit this problem early on. We're serializing things where NaN is
> > overloaded to mean both NaN and "uninitialized", and where +/- inf are
> > perfectly valid values. We often need to serialize structures between
> > runs that contain sections that haven't been initialized. A couple of
> > our platforms have exactly this bug.
> >
> > I'll dig up my changes and send them to you. IIRC they were three or
> > four lines each.
>
> How about adding a little bit to one of the files in serialization/test to
> test these things. Send that along with your changes. Probably adding a

But of course, you get no code from me w/o tests. :)

> couple of variables to A.hpp will be sufficient. Truth is, I don't even
> know
> how one goes about assigning a NaN or a +/inf to floating/double variable !!

I just had a thought:

So we'd rather not know about how the stream stores these things, we
just want it to work, round-trip. It should be as standard as
possible but (IIUC) the standard is fuzzy here, or at least it's
implementations are. So we're talking about code like
(basic_text_iprimitive):

void load(double & t)
{
   if(is.fail())
      boost::throw_exception(archive_exception(archive_exception::stream_error));
   char c = is.peek();
   while (c == ' ' || c == '\t' || c == '\n') // munch leading whitespace
   {
     is.get();
     c = is.peek();
   }
   if (c == 'n') // nan
   {
     t = NAN; // you can get one of those with 0.0/0.0, robert...
     if (is.get() != 'n' || is.get() != 'a' || is.get() != 'n')
        boost::throw_exception(archive_exception(archive_exception::stream_error));
     return;
   if (c == 'i') // positive inf
   {
      //etc, etc

Not real pretty and certainly not fast, if you want to read
positive-infinity as "inf" and negative infinity as "-inf", (which is
what comes out if you write them), you have to get and pushback that
minus sign.

Use case: I dump datastructures to XML with boost::serialization and
then I want to pick through them later with some homebrew utility like
a little python gui thing that makes graphs. I will have to
understand serialization's strategy for reading/writing these cases
and recode it myself... not good.

Also, the save routine contains code like:

os << std::setprecision(std::numeric_limits<float>::digits10 + 2);

Which is right there in lexical_cast.hpp. In addition, in
serialization you'll see code like:

    void load(unsigned char & t)
    {
        if(is.fail())
            boost::throw_exception(archive_exception(archive_exception::stream_error));
        unsigned short int i;
        is >> i;
        t = static_cast<unsigned char>(i);
    }

Where the archive is getting pretty up close and personal with the
types. Would it be too much to ask that lexical_cast<> handle these
nan-type situations, and delegate the job to lexical_cast<> (maybe
even for most or all PODs?)

-t


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