Intel® Fortran Compiler
Build applications that can scale for the future with optimized code designed for Intel® Xeon® and compatible processors.

Yet another "Unresoved externals"

tidi
Beginner
1,365 Views
Hi!
I am using some functions/subroutines from Numerical Recipes without any change.
Program contains only one calculation of gammp (incomplete gamma func.)

Code example (transcribed from NR):

CONTAINS
FUNCTION gammp(a,x)
! uses gser, gcf

END FUNCTION gammp

SUBROUTINE gser(gamser,a,x,gln)
! uses gammln

END SUBROUTINE gser

SUBROUTINE gcf(gammcf,a,x,gln)
! uses gammln

END SUBROUTINE gcf

FUNCTION gammln(xx)
REAL :: gammln,xx

END FUNCTION gammln

As You can see, function gammln is clearly defined.

But ifort (or MS linker) returns this error:


-out:gamma.exe
-subsystem:console
gamma.obj
gamma.obj : error LNK2019: unresolved external symbol _GAMMLN referenced in function _MAIN__
gamma.exe : fatal error LNK1120: 1 unresolved externals


PS: I am using ifort from command line.
0 Kudos
6 Replies
Jugoslav_Dujic
Valued Contributor II
1,365 Views
  • Are both the main program and GAMMLN in the same source file?
  • What is that CONTAINS statement part of?
0 Kudos
Steven_L_Intel1
Employee
1,365 Views
Given that you show a CONTAINS, I assume that this source defines a MODULE. That means you must add a USE of that module name in your program that calls GAMMLN.
0 Kudos
tidi
Beginner
1,365 Views
This "Contains" is part of main source file, i have not created module.

Source file:

Program Gamma
IMPLICIT NONE
REAL :: T, base, integral
Print*, "T = "
READ*, T
Print*, "base = "
READ*, base
integral = gammp(base, t)
Print*, integral
READ(*,*)

CONTAINS
FUNCTION gammp(a,x)
REAL a,gammp,x
REAL gammcf,gamser,gln
if(x.lt.0..or.a.le.0.)pause 'bad arguments in gammp'
if(x.lt.a+1.)then
call gser(gamser,a,x,gln)
gammp=gamser
else
call gcf(gammcf,a,x,gln)
gammp=1.-gammcf
endif
return
END FUNCTION gammp

SUBROUTINE gser(gamser,a,x,gln)
INTEGER ITMAX
REAL a,gamser,gln,x,EPS
PARAMETER (ITMAX=100,EPS=3.e-7)
INTEGER n
REAL ap,del,sum,gammln
gln=gammln(a)
if(x.le.0.)then
if(x.lt.0.)pause 'x gamser=0.
return
endif
ap=a
sum=1./a
del=sum
do n=1,ITMAX
ap=ap+1.
del=del*x/ap
sum=sum+del
if(abs(del).lt.abs(sum)*EPS)goto 1
enddo
pause 'a too large, ITMAX too small in gser'
1 gamser=sum*exp(-x+a*log(x)-gln)
return
END SUBROUTINE gser

SUBROUTINE gcf(gammcf,a,x,gln)
INTEGER ITMAX
REAL a,gammcf,gln,x,EPS,FPMIN
PARAMETER (ITMAX=100,EPS=3.e-7,FPMIN=1.e-30)
INTEGER i
REAL an,b,c,d,del,h,gammln
gln=gammln(a)
b=x+1.-a
c=1./FPMIN
d=1./b
h=d
do i=1,ITMAX
an=-i*(i-a)
b=b+2.
d=an*d+b
if(abs(d).lt.FPMIN)d=FPMIN
c=b+an/c
if(abs(c).lt.FPMIN)c=FPMIN
d=1./d
del=d*c
h=h*del
if(abs(del-1.).lt.EPS)goto 2
enddo
pause 'a too large, ITMAX too small in gcf'
2 gammcf=exp(-x+a*log(x)-gln)*h
return
END SUBROUTINE gcf

FUNCTION gammln(xx)
REAL :: gammln,xx
INTEGER j
DOUBLE PRECISION ser,stp,tmp,x,y,cof(6)
SAVE cof,stp
DATA cof,stp/76.18009172947146d0,-86.50532032941677d0,24.01409824083091d0, &
-1.231739572450155d0,.1208650973866179d-2,-.5395239384953d-5,2.5066282746310005d0/
x=xx
y=x
tmp=x+5.5d0
tmp=(x+0.5d0)*log(tmp)-tmp
ser=1.000000000190015d0
do j=1,6
y=y+1.d0
ser=ser+cof(j)/y
enddo
gammln=tmp+log(stp*ser/x)
return
END FUNCTION gammln
END Program
0 Kudos
tidi
Beginner
1,365 Views
PS: Compilation without line "integral = gammp(base, t)" returns no error message.
0 Kudos
Jugoslav_Dujic
Valued Contributor II
1,365 Views
Get rid of
REAL ... gamln
declarations in routines other than gamln.

Explanation: when you "glue together" different routines into single scope (as internal routines within the PROGRAM), you provide explicit interface, i.e. all other routines now "know" what GAMLN is. However, the (re)declaration "REAL GAMLN" says "ignore the neighboring GAMLN, there's another external GAMLN that you should use". Obviously, there isn't... thus the "unresolved external".

That's a common error when you "glue together" old F77 code into MODULEs or as internal routines: these FUNCTIONs were "bound" by EXTERNAL or REAL/INTEGER declarations, but once the code is merged, they become a burden.
0 Kudos
tidi
Beginner
1,365 Views
Thank You, problem solved!
0 Kudos
Reply