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

Segmentation fault when passing functions as arguments

gtokic
Beginner
775 Views
Hi,

I have a question regarding the proper use of functions as arguments. I have a code in which I often pass functions as arguments and the program runs properly using ifort 10.1.

Here is a sample code
[plain]module mod_util
 implicit none
 contains

   function do_something(n,func)
     implicit none
     integer,intent(in) :: n
     real               :: do_something(n+1)
     interface
       function func(x)
         implicit none
         real,intent(in) :: x(:)
         real            :: func(size(x))
       end function func
     end interface
     real                :: t(n+1)
     
     t = 1.0/(n+1)
     do_something = func(cos(t))/(n+1)
   end function do_something   
   
 end module mod_util

!*****************************************************************************

module module1
 implicit none
 contains
 
  function get_Am(Rn,N) result(Am_in)
    use mod_util,      only : do_something
    real,intent(in)          :: Rn(:)
    integer,intent(in)       :: N
    real                     :: Am_in(0:N)
    Am_in = 0.0
    Am_in = do_something(N,foo)
    
   contains
    
    function foo(x)
      real,intent(in)   :: x(:)
      real              :: foo(size(x))
      foo = 0.5*x*sum(Rn)
    end function foo 
         
  end function  get_Am  
  
  
end module module1

!*****************************************************************************  

program test_do_something
  use module1,    only : get_Am
  implicit none
  integer,parameter     :: N=5,NRn=2
  real                  :: Rn(0:NRn),Am(0:N)
  
  Rn = 0.1
  
  Am = get_Am(Rn,N)
  print *,' Am = ',Am

end program test_do_something
[/plain]

The code is organized in this way because mod_util module contains "crunching" procedures, which can get different functions to crunch from different parts of the code. Despite the probable bad programming practice, the code works fine under ifort 10.1. I have come across Steve's post http://software.intel.com/en-us/blogs/2009/09/02/doctor-fortran-in-think-thank-thunk/ where he mentions that use of interface blocks is not quite a good approach and using up-level references might lead to run-time errors. I wasn't aware of this before and since ifort didn't complain and the approach made sense to me i organized the entire code around that.

However, when I try compiling it on a differnent computer using pgf90, the code compiles but there is a segmentation error. The problem appears to be that Rn isn't defined in foo. I might find a way around it in this simple example, but there are other similar cases where this happens which would require the entire code to be rewritten. Am I doing something wrong with respect to FORTRAN standard, but what ifort is clever enough to correct?

Thanks a bunch,
Grgur
0 Kudos
1 Solution
Steven_L_Intel1
Employee
775 Views

I don't see a problem with your coide. As Tim correctly notes, passing an internal procedure as an argument is not standard F2003, but it is standard F2008, and the Intel compiler has supported this for many years.

It seems likely from your description that PGI does not support this extension - their support of F2003 is very limited to begin with, and they don't seem to try to match harder extensions (several vendors groused about this one at a Fortran standards meeting I attended - PGI is not on the committee.) I'm surprised that the compiler let you get away with it if they don't correctly support the extension in the manner the F2003 standard requires IF a compiler implements it.

As for the errors Tim mentioned, he used the Source Checker option which doesn't understand Fortran well at all.

View solution in original post

0 Kudos
5 Replies
TimP
Honored Contributor III
775 Views
This message:
grg.f90(36): error #12145: function "DO_SOMETHING" is called as subroutine
grg.f90(61): error #12145: function "GET_AM" is called as subroutine

seems to be evidence of a compiler bug in current ifort 11.1.
Passing an internal procedure as a procedure argument (a fairly popular feature) wasn't permitted in f95 or f2003, and so is rejected by several compilers, although ifort should have supported it for a long time (and more compilers should begin doing so):

grg.f90(36): warning #7601: F2003 standard does not allow an internal procedure
to be an actual argument procedure name. (R1214.4). [FOO]
Am_in = do_something(N,foo)
0 Kudos
Steven_L_Intel1
Employee
776 Views

I don't see a problem with your coide. As Tim correctly notes, passing an internal procedure as an argument is not standard F2003, but it is standard F2008, and the Intel compiler has supported this for many years.

It seems likely from your description that PGI does not support this extension - their support of F2003 is very limited to begin with, and they don't seem to try to match harder extensions (several vendors groused about this one at a Fortran standards meeting I attended - PGI is not on the committee.) I'm surprised that the compiler let you get away with it if they don't correctly support the extension in the manner the F2003 standard requires IF a compiler implements it.

As for the errors Tim mentioned, he used the Source Checker option which doesn't understand Fortran well at all.
0 Kudos
gtokic
Beginner
775 Views

I don't see a problem with your coide. As Tim correctly notes, passing an internal procedure as an argument is not standard F2003, but it is standard F2008, and the Intel compiler has supported this for many years.

It seems likely from your description that PGI does not support this extension - their support of F2003 is very limited to begin with, and they don't seem to try to match harder extensions (several vendors groused about this one at a Fortran standards meeting I attended - PGI is not on the committee.) I'm surprised that the compiler let you get away with it if they don't correctly support the extension in the manner the F2003 standard requires IF a compiler implements it.

As for the errors Tim mentioned, he used the Source Checker option which doesn't understand Fortran well at all.

Hi Tim, Steve,

Thanks a lot for your feedback. At least now I know I'm not crazy, I couldn't understand what's wrong with my code. Since I don't have an alternative to running the code on the computer with pgf90, do you have some suggestion/advice how to alter the code such that it conforms with their fortran implementation?

Thanks once again,
Grgur
0 Kudos
TimP
Honored Contributor III
775 Views
Quoting - gtokic
Since I don't have an alternative to running the code on the computer with pgf90, do you have some suggestion/advice how to alter the code such that it conforms with their fortran implementation?

Unfortunately, if you want to make procedure arguments strictly compatible with f95 and f2003, you must use external procedures.
0 Kudos
gtokic
Beginner
775 Views
Quoting - tim18
Unfortunately, if you want to make procedure arguments strictly compatible with f95 and f2003, you must use external procedures.

Hi Tim,

Thanks for the suggestion. Unfortunately indeed, but if that's the only way to get the code to run...

Best,
Grgur
0 Kudos
Reply