Intel® Fortran Compiler
Build applications that can scale for the future with optimized code designed for Intel® Xeon® and compatible processors.
Announcements
FPGA community forums and blogs on community.intel.com are migrating to the new Altera Community and are read-only. For urgent support needs during this transition, please visit the FPGA Design Resources page or contact an Altera Authorized Distributor.
29281 Discussions

Why do Functions and Subroutines compile differently?

scriabin3
Beginner
692 Views
Please help me understand this:

MAIN program "contains" routines F1 and F2. MAIN calls F1 which in turn calls F2.

If F1 and F2 are Subroutines, then the program compiles and runs just fine. But if F1 and F2 are Functions, then the program gives a compilation error: Undefined symbols: "_F2_", referenced from: _MAIN__
In the latter case, what do I need to do to make the compiler "see" F2?
Here are example programs that display the above behavior:
!-------------------------
program test1
real :: x,a1
x=5.
call f1(x,a1)
print*, a1
contains
subroutine f1(x,a1)
real, intent(in) :: x
real, intent(out) :: a1
call f2(x,a1)
end subroutine f1
subroutine f2(x,a1)
real, intent(in) :: x
real, intent(out) :: a1
a1=2.*x
end subroutine f2
end program test1
!-------------------------
program test2
real :: x,a1
x=5.
a1=f1(x)
print*, a1
contains
function f1(x)
real :: f1,f2
real, intent(in) :: x
f1=f2(x)
end function f1
function f2(x)
real :: f2
real, intent(in) :: x
f2=2.*x
end function f2
end program test2
!-------------------------
0 Kudos
1 Solution
mecej4
Honored Contributor III
692 Views
In the second program, the one which uses functions f1 and f2, replace

real:: f1,f2

by

real :: f1

and run the program. Then, read the manuals on the topic of "host-association".

What happens is that in the body of internal function f1(x), the declaration of f2 as real overwrites the host-association of f2. Since f2 is already available and its attributes are known to the compiler by host-association, a redeclaration of f2 as real tells the compiler to override the previous instance of f2.


View solution in original post

0 Kudos
3 Replies
forcpp
New Contributor I
692 Views
Interestingly your both versions of the same code work fine with gfortran. Also if we write the second code like below, we get the right result by ifort too.
[fortran]program test2
  real :: x,a1
  real, external :: f1
  x=5.
  a1=f1(x)
  print*, a1
end program test2

  function f1(x)
    real :: f1,f2
    real, intent(in) :: x
    f1=f2(x)
  end function f1

  function f2(x)
    real :: f2
    real, intent(in) :: x
    f2=2.*x
  end function f2[/fortran]


0 Kudos
mecej4
Honored Contributor III
693 Views
In the second program, the one which uses functions f1 and f2, replace

real:: f1,f2

by

real :: f1

and run the program. Then, read the manuals on the topic of "host-association".

What happens is that in the body of internal function f1(x), the declaration of f2 as real overwrites the host-association of f2. Since f2 is already available and its attributes are known to the compiler by host-association, a redeclaration of f2 as real tells the compiler to override the previous instance of f2.


0 Kudos
scriabin3
Beginner
692 Views
Thank you! So obvious, after your explanation.
0 Kudos
Reply