This is the mail archive of the
gcc-bugs@gcc.gnu.org
mailing list for the GCC project.
[Bug fortran/34345] gfortran compiles SLATEC library, but the executable fails
- From: "kargl at gcc dot gnu dot org" <gcc-bugzilla at gcc dot gnu dot org>
- To: gcc-bugs at gcc dot gnu dot org
- Date: 6 Dec 2007 19:13:45 -0000
- Subject: [Bug fortran/34345] gfortran compiles SLATEC library, but the executable fails
- References: <bug-34345-15478@http.gcc.gnu.org/bugzilla/>
- Reply-to: gcc-bugzilla at gcc dot gnu dot org
------- 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