1
votes

I am building a program that must call a subroutine in a function subprogram and be able to call the same subroutine in the main program.

 program main
 implicit double precision (a-h,o-z)
 parameter (ncmax=20)
 dimension z(ncmax)

 xI=1.0
 xII=2.0
 z(1)=1.0

 outI = fncn (xI,xII,z,ncmax)

 call Sub (xI,xII,xIII,z)
 outII = 2.0*xIII

 end program


 function fncn (xI,xII,z,ncmax)
 implicit double precision (a-h,o-z)
 dimension z(ncmax)

 Call Sub (xI,xII,xIII,z)
 fncn = xIII

 return
 end function


 subroutine Sub (xI,xII,xIII,z)
 parameter (ncmax=20)
 implicit double precision (a-h,o-z)
 dimension z(ncmax) 

 xIII = xI + xII + z(1)

 return 
 end subroutine

This is all in fixed format fortran 77 ('.f' extension). The error I receive is a segmentation fault. Am I supposed to make a module as some of the other posts on this site suggest? I am still a beginner and am not sure how to make a module in 77. The subroutine must be able to be accessed in the function and in the main program. My current program structure has the function and subroutine split into two separate .f files and include statements are used at the end of main.

I searched this site for similar problems and could only find help regarding fortran 90. I am using gfortran from gcc 4.6.1.

EDIT: I solved the problem. The subroutine that I was attempting to call in the function had both numerical and character outputs. I was overlooking the character outputs and did not have a character defined variable to handle the character output. Once I defined a character variable within the function everything worked fine. Thank you everyone for your patience and help.

2
Can you compile the code with -g and then run it in a debugger? I am curious why it would segfault at all (since I too don't see any apparent reason for a segfault). - Hristo Iliev
I made an oversight when I was writing this example code. I forgot about the use of common blocks in the actual subroutine I am trying to use. My main program contains the common blocks but I forgot to copy them over to my function program. - kxk7607

2 Answers

3
votes

If you really don't have to use FORTRAN 77, don't use it. Forget about IMPLICIT even in Fortran 77! IMPLICIT NONE is present in almost all FORTRAN 77 compilers as an extension. It is almost necessary in all sane code for last 25 or 30 years. It was the 60`s and maybe early 70's way to shorten the code.

Place all your subroutines and functions in modules and use it, this will ensure you are calling them correctly, or at least not totally wrong. This the Fortran 90 and later way to go. Avoid it only when you really have to.

The return statements are redundant, the subroutine returns et the end anyway, what other thing it should do?

Finally I did not find any error or compiler warning when compiling your code yet. I even used valgrind. I also used gfortran-4.5.4 and gfortran-4.6.3 and also Solaris Studio on Linux.

1
votes

I agree with Vladimer F. Implicit typing is pernicious. Also with using modules Why use FORTRAN 77 when improved versions of Fortran have been available for so many years? Your program worked when I tried it. Here is a quick and minimal translation into Fortran 90:

module my_subs

implicit none

contains

function fncn (xI,xII,z,ncmax)
integer :: ncmax
double precision :: z(ncmax)
double precision :: xI, xII, xIII
double precision :: fncn

Call Sub (xI,xII,xIII,z,ncmax)
fncn = xIII

return
end function


subroutine Sub (xI,xII,xIII,z,ncmax)
integer :: ncmax
double precision :: z(ncmax)
double precision :: xI, xII, xIII

xIII = xI + xII + z(1)

return
end subroutine

end module my_subs


program main
use my_subs
implicit none
integer, parameter :: ncmax=20
double precision :: z(ncmax)
double precision :: xI, xII, xIII, outI, outII

xI=1.0
xII=2.0
z(1)=1.0

outI = fncn (xI,xII,z,ncmax)

call Sub (xI,xII,xIII,z,ncmax)
outII = 2.0*xIII

write (*, *) outII

end program