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]

RE: Robust detection of endianness at compile time.


Andrew, thanks for your thoughts!


Andrew Haley wrote:

> It would work on gcc, because gcc allows members of a union to be 
> written as one type and read as a different incompatible type.
> Other C compilers allow this too.  However, it's is not guaranteed by 
> the language standards, so it doesn't much help you with truly 
> portable code.

  Stroustrup in his "C++ Programming Language, 3rd Ed." doesn't say that
using a union in this way is forbidden, he just feels (strongly) that the
use of unions for type conversion is a misuse of unions and that it is
"cheating".  However, and with all due respect to Stroustrup, he has
apparently missed the need, rare though it might be, to be able to
manipulate floats and doubles as bit-fields.  

  The new reinterpret-cast could have been an opportunity to provide this
capability: (page 256): 
"In most cases, it simply yields a value with the same bit pattern as its
argument with the type required.  Thus, it can be used for the inherently
implementation-dependent, dangerous, and occasionally absolutely necessary
activity of converting integer values to pointers and vice versa."

  Alas, the reinterpret-cast produces an "invalid reinterpret_cast" compile
error (is this possibly a bug?).

The useful output would be the actual bit-pattern of the double, which would
look like this (formatted as sign, exponent, mantissa) for the double value
1.5:

0 01111111111 1000000000000000000000000000000000000000000000000000

The union is the only way I know to get this using c/c++:
  union Dbits {
    double d;
    ULL bits;
  }
It is very efficient requiring no method calls or other overhead.  (Note
that Java at least recognized this need with its
Double.doubleToRawLongBits() and related methods.)

  So how "implementation-dependent and dangerous" is this conversion?

1) IEEE-754: Today the IEEE-754 standard (especially the 32 and 64 bit
formats) is the most widely-used standard for floating point computation by
far.  For the increasingly rare machines that don't support this
standard...well, fortunately, I don't need to worry about writing reusable
code for them.

2) unsigned long long (ULL): now this may be dangerous.  I have not figured
out a way to define an integral type that is EXACTLY 64 bits ...Other than
using <limits> and testing to see if, in fact, that ULL has that number of
bits and then if it doesn't, throw an error.  GCC provides ULL at 64 bits,
but my understanding is that "it is not guaranteed by the language
standards" either (it isn't even mentioned!).  

Compared to using a union for int to pointer conversion, which I consider
far more dangerous, I think that getting a simple, fast and efficient
facility for floatToInt and doubleToULL (& visa versa) would be very useful.


Lee.
 












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