------- 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

Reply via email to