Re: Integers and standard

In article <8_-dnaJ6Rckq6hPVnZ2dnUVZ_tjinZ2d@xxxxxxxxxxx>,
"James Van Buskirk" <not_valid@xxxxxxxxxxx> writes:
"Alfredo Buttari" <alfredo.buttari@xxxxxxxxx> wrote in message

I have a quick question. Is the following piece legal according to
fortran 77 and/or 90/95 standard?

integer i
data i/z'80000000'/

As far as my understanding goes, it is not but many compilers (intel,
xlf, gfortran 4.2) don't complain about it while others do (g77 gives
a warning, gfortran 4.3 an error).

The problem is that I need to declare this value in a Fortran
interface for a C package that uses the value internally (and, as you
know, this is a legal value in C). Do you know any way to work around

This is an ugly point in a language that only has unsigned integers.
The f08 standard, N1723.pdf, sections 13.3.1, 13.3.3, and 13.7.81
offer clarification on what is supposed to happen if you say:

integer :: i = int(z'80000000')

You get a processor-dependent value which, on machines with 2's
complement 32-bit default integers will be the number with only
the sign bit set. Let's see if gfortran gets this right yet:

C:\gcc_mingw64\clf\ovl>type ovl1.f90
program ovl1
implicit none
integer :: i = int(z'80000000')

write(*,'(z8.8)') i
end program ovl1

C:\gcc_mingw64\clf\ovl>gfortran ovl1.f90 -oovl1

integer :: i = int(z'80000000')
Error: Arithmetic overflow converting INTEGER(16) to INTEGER(4) at (1). This
check can be disabled with the option -fno-range-check

What does F2003 say about BOZ in INT(), REAL(), etc.?

gfortran is a Fortran 95 with some 2003 feature and even fewer
features from a draft of the yet-to-be F2008.

So the answer seems to be in the negative. Well, how about:

C:\gcc_mingw64\clf\ovl>type ovl2.f90
program ovl2
implicit none
integer i
character temp*80

i = ishft(1,bit_size(i)-1)
write(*,'(z8.8)') i
write(temp,'(i0)') i
read(temp,'(i11)') i
write(*,'(z8.8)') i
end program ovl2

C:\gcc_mingw64\clf\ovl>gfortran ovl2.f90 -oovl2

At line 9 of file ovl2.f90
Fortran runtime error: Value overflowed during integer read

Well, that's a shame, too. gfortran has problems with detection
of integer overflow in that it generates false positives and there
isn't always an obvious way to work around them or turn off the
overflow detection.

Well, one could read the manual.

mobile:kargl[209] ~/work/bin/gfortran -static -fno-range-check -o z m.f90
mobile:kargl[210] ./z
mobile:kargl[211] ~/work/bin/gfortran -static -o z m.f90
mobile:kargl[212] ./z
At line 9 of file m.f90
Fortran runtime error: Value overflowed during integer read

There are some ambiguous cases, e.g.

integer, parameter :: ik1 = selected_int_kind(2)
integer i

i = -128_ik1 ! unambiguous
i = -128_ik1*2 ! ambiguous, should be detected

The first case above could be fixed in the standard so that compilers
don't make it so awkward to express the most negative number. The
second case is a clear programming mistake in that the multiplication
operation has precedence in Fortran over unary negation so that the
result would be something like +256 considering that 128_ik1 would
overflow to -128_ik1 ... Failure to detect the second case is about
as bad as allowing iterated operators (e.g. 2**-3*4 is evaluated
differently among the compilers that do so.)

Huh? Both cases are detected. 128_ik1 overflows it kind. In both
cases, you have a unary minus operator.

mobile:kargl[220] ~/work/bin/gfortran -static -o z k.f90

i = -128_ik1 ! unambiguous
Error: Integer too big for its kind at (1). This check can be disabled with
the option -fno-range-check

i = -128_ik1*2 ! ambiguous, should be detected
Error: Integer too big for its kind at (1). This check can be disabled with
the option -fno-range-check