Boost logo

Boost :

Subject: Re: [boost] [endian] Some suggestions
From: Beman Dawes (bdawes_at_[hidden])
Date: 2016-04-13 06:57:42


On Sun, Apr 10, 2016 at 10:01 AM, Peter Dimov <lists_at_[hidden]> wrote:

> Beman Dawes wrote:
>
>> The problem isn't when storing into the char buffer, but later on a
>> different machine or compiler when the char buffer has to be converted to a
>> float type.
>>
>> In testing, I even ran into a case were on the same machine and compiler
>> the float data failed to round-trip correctly if the program that created
>> the file was compiled with a different set of optimization options that the
>> program the read the file.
>>
>
> Perhaps you could go into more detail here, because I'm not sure I
> understand the nature of the problem.
>

Sorry, I misspoke. I went back and found my original notes. My test program
mistakenly depended on std::numeric_limits<...>::signaling_NaN(), and
standard library implementations are free to use different values for that.
For example, clang/c2 on Windows uses a different value than clang on
Ubuntu.

>
> Intuitively, if you have a little-endian IEEE platform, and you write the
> float out to disk, and then you read that back (even if using different
> optimization options), you ought to end up with the same float, because
> this is no different than memcpy'ing one float to another.
>
> float x = ..., y;
>
> memcpy( &y, &x, sizeof(float));
> // y should contain x
>
> unsigned char buffer[ sizeof(float) ];
> memcpy( buffer, &x, sizeof(float));
> memcpy( &y, buffer, sizeof(float));
> // should be the same as above
>
> unsigned char buffer[ sizeof(float) ];
> memcpy( buffer, &x, sizeof(float));
> // store buffer to disk
> // ...
> // load buffer from disk
> memcpy( &y, buffer, sizeof(float));
> // should be the same as above
>
> At which point do things break?
>

They don't, because in that example you are careful to avoid direct use of
"float".

>
> Furthermore, if the "store buffer" and "load buffer" lines byteswap, this
> makes no difference.
>

Agreed.

>
> Now, if you don't store or load "buffer" but a "float" directly, and then
> byteswap that float directly in place, I wouldn't bet on that working. But
> there's no need to do so.

Agreed, and directly byteswapping a float is avoided in the endian buffer
and endian arithmetic classes. But to follow the same pattern as the
conversion functions, the interface would look like this:

         float endian_reverse(float x) noexcept;

but like you and whoever raised the issue originally, I don't want to bet
on that working.

--Beman


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