This is the mail archive of the gcc-help@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Byteswapping floating point types


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


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]