Hi all,
I'm having an argument about byteswapping floating point types and
since the argument is mainly concerning the behavior of the compiler
(and in this case of GCC specifically) I figure this list is a good
place to ask for information.
A co-worker has preposed this function (simplified here) for providing
byteswaping for both integral and floating point types.
template<class T>
T byteswap(T value)
{
T result;
size_t n = sizeof (T);
unsigned char* p = (unsigned char*) &value;
for (size_t i = 0; i < n; ++i)
((unsigned char*) &result)[i] = p[n - 1 - i];
return result;
}
Now, aside from the fact that this template is _too_ generic and
accepts things it really shouldn't, it does successfully byteswap both
integral and floating point types. I believe that manipulating the
underlying bytes of floating point values via access through unsigned
char* should be safe, as opposed to a methods of byteswaping by
leveraging unions which breaks aliasing rules.
But for floating point types doesn't this signature run the risk of
the compiler putting a byteswapped floating point value into an FPU
register, thus causing the data to be modified?
Testing with GCC 3.5.x to GCC 4.x has shown that this issue doesn't
surface unless you attempt some mathematical operation on the float
containing a byteswaped value. In other words:
// This works
float before = 50.125484;
float swapped = byteswap (before);
float after = byteswap (swapped);
assert (before == after);
// This fails
float before = 50.125484;
float swapped = byteswap (before);
swapped += 0;
float after = byteswap (swapped);
assert (before == after);
My concern is that the compiler is free to put floating point values
into FPU registers as it sees fit and relying on the compiler not
doing so is dangerous. He feels that my concern is misguided and if
his implementation of byteswap() doesn't work it's because the
compiler is broken or someone is trying to do something with
byteswapped floating point values that they shouldn't be doing.
Who is in the right here?
--
Andrew Troschinetz
Applied Research Laboratories