Reputation: 413
Dear Fortran Programmers,
I am quite confused with the behaviour of the following piece of simple fortran code
program foo
implicit double precision (a-h,p-w), integer*8(i-n),
+ character*12(x-z)
xx = 'not working '
call lskip(xx,4,8)
call lskip2(xx,4,8)
end
subroutine lskip(xxx,n,m)
implicit double precision (a-h,p-w), integer*8(i-n),
+ character*12(x-z)
print*, ' ine lskip ',xxx,n,m
return
end
subroutine lskip2(xxx,n,m)
character*(*) xxx
print*, ' ine lskip2 ',xxx,n,m
return
end
with gfortran-4.2.1
the it prints something as follows.
ine lskip not working 7308894831428763652 17179869192
ine lskip2 not working 4 8
and with intel's ifort-12.1.2
the output looks like;
ine lskip not working 34359738372 8
ine lskip2 not working 4 8
what is wrong with subroutine lskip()
? Why can't I use the implicit declaration
again in this case?
Upvotes: 0
Views: 3114
Reputation: 29381
Adding to the existing answers... If the program were written to use the features of Fortran 90 the compiler will automatically find the problem. With the subroutine in a module and the module use
d by the program, the compiler will check the arguments for consistency. One of MANY reasons to switch from FORTRAN 77 to Fortran 90.
A quick conversion to Fortran 90:
module MyStuff
contains
subroutine lskip(xxx,n,m)
implicit double precision (a-h,p-w), integer*8(i-n), character*12(x-z)
print*, ' ine lskip ',xxx,n,m
return
end
subroutine lskip2(xxx,n,m)
character*(*) xxx
print*, ' ine lskip2 ',xxx,n,m
return
end
end module MyStuff
program foo
use MyStuff
implicit double precision (a-h,p-w), integer*8(i-n), character*12(x-z)
xx = 'not working '
call lskip(xx,4,8)
call lskip2(xx,4,8)
end
This conversion doesn't eliminate implicit typing, which I fully agree should never be used.
And compiling this version, gfortran 4.9 says:
MyStuff.f90:22.17:
call lskip(xx,4,8)
1
Error: Type mismatch in argument 'n' at (1); passed INTEGER(4) to INTEGER(8)
Upvotes: 1
Reputation: 2953
The compiler is not throwing a warning, but you are passing integer literals of the wrong precision here:
call lskip(xx,4,8)
Subroutine lskip
expects the arguments to be integer*8
while 4 and 8 have the default precision of integer*4
.
A correct call in this case could be
call lskip(xx, 4_8, 8_8)
However, unless this is some legacy code handed to you, I strongly suggest avoiding writing any code in this style, which is Fortran 77 (fixed form source, no modules). Especially, since programs no longer have to fit on punch cards, do not use implicit typing anywhere, as it is the source of many evils.
A good habit is therefore to put this in the parent scope of your programs:
implicit none
Upvotes: 2
Reputation: 18098
You are passing a default kind integer (usually integer*4
) to an integer*8
, so the representation of the integers does not match, resulting in garbage.
In the second case you are using default integers in the subroutine as well, so everything works out as expected. If you used variables in the main program to hold the values for the first and second argument, the values would be converted to the specified kind:
i1 = 4
i2 = 8
call lskip(xx,i1,i2)
Upvotes: 0