Re: Integers and standard



"Alfredo Buttari" <alfredo.buttari@xxxxxxxxx> wrote in message
news:c552607b-b03f-4388-a7a4-557d675ff4e7@xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

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?

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
ovl1.f90:3.22:

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

write(*,'(z8.8)') i
1
Error: Symbol 'i' at (1) has no IMPLICIT type

C:\gcc_mingw64\clf\ovl>gfortran -v
Using built-in specs.
Target: x86_64-pc-mingw32
Configured with:
.../gcc/configure --prefix=/var/tmp/win64 --with-sysroot=/var/tm
p/win64 --target=x86_64-pc-mingw32 --host=x86_64-pc-mingw32 -q --silent
Thread model: win32
gcc version 4.4.0 20080724 (experimental) (GCC)

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

C:\gcc_mingw64\clf\ovl>ovl2
80000000
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. 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.)

It can be quite useful for the programmer to assume an internal
representation for integers (not to say logicals and reals) and
to be able to manipulate them accordingly without the compiler
tying both hands behind your back when you try to do so.

--
write(*,*) transfer((/17.392111325966148d0,6.5794487871554595D-85, &
6.0134700243160014d-154/),(/'x'/)); end


.