------- Comment #5 from kargl at gcc dot gnu dot org 2007-12-06 19:13 ------- (In reply to comment #4) > I have several programs (f77 and f90) that do this and their intent is clear - > just put the bit patterns into to words as requested - no data conversion - no > range checking.
Which is of course nonstandard. The F95 standard is quite clear on where a BOZ can appear and that a BOZ is an integer. > BOZ seems to have been created for this purpose, Maybe. BOZ doesn't appear in my copy of the F77 standard (on a quick scan), and I don't have a copy of F90 to check. However, F95 is quite clear on BOZ > but the committee seems the have lost track of why programs need specific > bit patterns and how they are used. See the TRANSFER intrinsic. I think J3 recognized the problems with specify a bit pattern. J3 also appears to have recognized the limitations on TRANSFER because they have allowed BOZ to appear in REAL, INT, DBLE, and COMPLX. Unfortunately, J3 didn't define what this means! > How about adding something like a "-fhex" enhancement > that does this ? This is a very nontrivial option to add, and it opens the door to (mis)feature creep of a extension. What happens with subroutine add(y, x) real x, y do i = 1, 10000000 x = y + Z'deadbeef' + 42 end do end subroutine Is Z'deadbeef' an integer or a real? If one uses the normal rules of Fortran and using BOZ for short, a compiler can do either x = (y + BOZ) + 42 ! Conversion of BOZ to real??? or x = y + (BOZ + 42) ! Conversion of BOZ to integer??? Note, the latter form allows the compiler to constant fold and hoist (BOZ + 42) out of the loop; thereby saving 1 million additions. I suppose one could argue that the scanner can recognize that a BOZ is present in the expression and then promote it to the highest type. The above would then become x = y + REAL(BOZ, kind(y)) + 42 or, perhaps, x = y + REAL(BOZ, kind(x)) + 42 ! x is double prec and y is REAL? because the programmer obviously meant the BOZ should have the same kind as the LHS. In the end, one would probably want x = y + REAL(BOZ, max(kind(x), kind(y))) + 42 to avoid possible loss of precision in the BOZ. Here's a more complicated example module fun interface whoops module procedure p_int module procedure p_real end interface contains subroutine p_int(x) integer, intent(in) :: x print '(I0)', x end subroutine p_int subroutine p_real(x) real, intent(in) :: x print '(ES12.4)', x end subroutine p_real end module fun use fun call whoops(Z'deadbeef') ! Is this an integer or real??? end program I suppose that one can argue that gfortran can restrict BOZ to the simplest form of an initialization expression. real, parameter :: x = z'deadbeef' ! Allowed real bit pattern real, parameter :: y = z'deadbeef'+1. ! Not allowed, BOZ in a RHS expression This argument, IMHO, boils down to "I don't care what gfortan does as along as it does what I want." Now for the fun. How is z'deadbeef' interpreted on big and little endian hardware? Before you scoff, realize that gfortran has to convert the BOZ into something that MPFR can digest. This means that gfortran has do something like z'deadbeef' --> -0X3.ABC123p2 where the number following p is the exponent in base 16. I've, of course, not discussed whether the exponent portion of z'deadbeef' is a biased or unbiased exponent. I guess gfortran will assume that it is biased. Now, what integer value are you subtracting to get the 2 that follows the p? There's even more fun if the BOZ is too small. What does gfortran do with z'dead'? Is this z'dead0000' or z'0000dead' or is this literally only 2 bytes and the other 2 bytes are whatever is currently in memory? Having spent a considerable amount of time thinking about ways to "fix", I can assure you that it isn't a simple matter of just adding -fhex. -- http://gcc.gnu.org/bugzilla/show_bug.cgi?id=34345