Boost logo

Boost Users :

From: Robert Ramey (ramey_at_[hidden])
Date: 2005-01-05 20:17:29


The simple truth is I never consider this.

When it came up the last time I didn't really think about it very much as I
was involved in other things and I hoped intereste parties might come to a
consensus without my having to bend my over-stretched brain.

Austin Bingham wrote:
> I saw a thread on this topic from a few months ago, and I was
> wondering if there had been any progress or new thought on the topic.
> Essentially, it appears that the serialization library can't reliably
> deserialize the serialized version of NaN and infinity for doubles and
> floats. This seems to be a result of relying on the, AFAIK, undefined
> behavior of writing NaN/infinity to a stream; it will work correctly
> with some standard library implementations, but not all.
>
> I think the problem can be addressed with these changes:
>
> basic_text_oprimitive::save(float or double): on NaN or Infinity,
> write out some known, stable string (i.e. "nan" or "inf"); don't rely
> on std implementation.
>
> basic_text_iprimitive::load(float or double): look for the "known
> values" printed by save(), generating the correct values when they're
> seen.

I'm not convinced this would work very well. when loading a data value, you
have to know ahead of time what type its going to be - float or string.

Here are a couple random thoughts on this issue

a) I believe that native binary archives will handle this without out change
as they just copy the bits to the archive and back. As long as you read the
archive on the same compiler/os/machine, there should be no issue.

b)define a special type for Nan:

class NanType {};

Use variant serialization

ar << boost::variant<NanType, float>(value)

boost::variant x;
ar >> x;

Of course this presumes that one has implemented serialization for
boost::variant. I havn't done this but I did receive code from someone who
did. I wanted to upload it to the boost file section but the fiile section
was full. I noted this on this list but so far no one has responded.

c) a simpler approximation of the above could easily be made.

class NanOrNot {
bool Nan;
float & value; // its its not a Nan
template<class Archive>
void save(Archvive &ar, unsigned int version){
    ar << Nan;
    if(! Nan)
        ar << Value;
}
template<class Archive>
void load(Archive &ar, unsigned int version{
    ar >> Nan;
    if(! Nan)
        ar >> Value;
}
NanOrNot(float & t){
    value(t)
{
    // initialize Nan
}
BOOST_MEMBER_SPLIT
};

...
float x;
...

ar << NanOrNot(x)

etc.

which i believe is more or less what you have in mind. This is would be a
serialization wrapper which is explained in the documentation. An example
of a complete serialization wrapper is NameValuePair. Once you had a
wrapper you could just

This approach would have a couple of valuable features:
1) its usage is optional. This would keep machine cycle misers happy.
2) it wouldn't require changing any archive class implemention - this would
keep me happy.

Just random ideas - I'm not going to start defending them.

Robert Ramey


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