On Sun, Apr 10, 2016 at 10:01 AM, Peter Dimov
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