UCU110
UCU110

Reputation: 413

Fortran passing numbers to subroutines

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

Answers (3)

M. S. B.
M. S. B.

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 used 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

sigma
sigma

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

Alexander Vogt
Alexander Vogt

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

Related Questions