This is the mail archive of the
gcc-bugs@gcc.gnu.org
mailing list for the GCC project.
[Bug fortran/29471] Warn with -std=f95/f2003 when BOZ is used at invalid places
- From: "burnus at gcc dot gnu dot org" <gcc-bugzilla at gcc dot gnu dot org>
- To: gcc-bugs at gcc dot gnu dot org
- Date: 16 Mar 2007 09:45:30 -0000
- Subject: [Bug fortran/29471] Warn with -std=f95/f2003 when BOZ is used at invalid places
- References: <bug-29471-1719@http.gcc.gnu.org/bugzilla/>
- Reply-to: gcc-bugzilla at gcc dot gnu dot org
------- Comment #9 from burnus at gcc dot gnu dot org 2007-03-16 09:45 -------
> The current problem is shown in this bit of code:
> write(*,*)'NaN(8)=',real(z'FFF8000000000000',8)
> end
Note: gfortran does not support Fortran 2003 BOZ yet.
> gfortran, even with -std=f2003, claims that the BOZ data is too big.
Use -fno-range-check to disable this checking. But this will still the old BOZ
extension and not the Fortran 2003 BOZ.
> Even without the reinterpret cast problem, integer BOZ is not handled
> correctly. This expression also claims the BOZ is too large:
> int(z'FFFFFFFFFFFFFFFF',8)
The number is does not fit into -huge(1_8) ... huge(1_8) and is therefore
outside of the Fortran standard. -> -fno-range-check
> The traditional behavior is for all BOZ to be initially interpreted as the
> largets integer type supported.
Which is why gfortran gives no error if you use int(BOZ, kind=16).
> The only hassle with "processor dependent" definitions is that the result of a
> given binary value depends on a processor's internal binary format. So, IEEE
> floats are portable, but other long/quad real numbers are not.
"Processor dependent" in the Fortran language does not only mean the CPU but
also the compiler; nonetheless, in this regard most (all?) compilers produce
the same result on a given platform.
> A related problem is that I am trying to create a NaN constant (parameter). I
> can't use REAL+BOZ, but I also cannot define "real :: NaN = 0.0/0.0". In this
> case, divide-by-zero is invalid math, but should only be a warning and not an
> error. (I am speaking practically; I don't know what the standards say.)
The standard does not say anything about non-Fortran numbers. Fortran 2003 has
now support of the IEEE arithmetics, which allows NaN, denormalized numbers and
+/-INF, overflowing etc.
Thus for a Fortran 95 compiler, the 0./0. can always be rejected, whereas for
Fortran 2003 it is a bit unclearer (cf. below for a standard way to get Nan).
my personal trick is to use:
real :: r, NaN
r = 0.0
NaN = 0.0/r
which does the NaN at run time. (You still need to have the right compiler
flags as otherwise you get an arithmetic exception at run time.)
> But, good news, I just discovered that this hack works:
> NaN = transfer(ishft(int(z'FFF80000',8),32),0.0_8)
> I tried that a while back with gfortran and it crashed.
A modified version still crashes with gfortran:
real(kind(0d0)) :: NaN = transfer(ishft(int(z'FFF80000',8),32),0d0)
print *, NaN
Interestingly, this produces "0.0" with ifort, while g95 and sunf95 give "NaN".
See PR 31194.
> What we really need is a NAN(kind=8) intrinsic.
Well, one can do in Fortran 2003:
use,intrinsic :: ieee_arithmetic
real :: NaN
NaN = ieee_value(x,ieee_quiet_nan)
(Note: IEEE arithmetic is not yet supported by many compilers, especially
gfortran does not support it yet.)
(In reply to comment #6)
> My vote is to just ignore the standards when it
> comes to negative BOZ, the way Intel has done it, which I HOPE is what F2008
> says.
Sorry, I think most people would like to have a standard conform compiler; we
cannot do so.
Besides IEEE arithmetic allows what you want. Using transfer is a non-portable
way to do so, which assumes a certain internal structure. And using your
integer BOZ are supported with -fno-range-check.
--
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=29471