\digression
I'm C++ programmer, with occasional visits to FORTRAN, the problem
arose from interfacing c++ to fortran, and if necessary, I'll post
complete (and minimal) example that resembles my problem.
\end digression
I'm experiencing difficulties declaring function that has another
function as as argument, using interface block; for example:
I have two functions, f1, and fcn. In main program ,I would like to
call function fcn with f1 as actual argument, but don't know how to
declare it within interface block in main program.
real function f1(x)
implicit none
real x
f = x*2.0
end
real function fcn(x,f)
implicit none
real x
interface
function f(x)
real f,x
end function
end interface
fcn = f(x)
end
program main
implicit none
interface
function fcn(x,f)
real fcn,x
! problem: declaring function parameter f?
end function
end interface
print *, fcn(10.0, f1)
stop
end
Gordan
Alas, Fortran 9x does not have "typedefs" for routine prototypes.
You have to spell out entire prototype each time you need it.
Thus, you may embed INTERFACE blocks recursively:
interface
function fcn(x,f)
real fcn,x
interface
function f(x)
real f,x
end function
end interface
end function
end interface
(Don't ask what would happen if dummy argument X of F were also a
function :-) ).
You may also take a look at EXTERNAL attribute. It may serve as
a "light" INTERFACE block for your purpose, keeping the things
simpler (esp. in the mixed-language environment) on the expense
of type safety. For example:
interface
function fcn(x,f)
real fcn,x
real, external:: F
end function
end interface
<digression>
I presume you know you can get the explicit interfaces in an
easier way, using MODULEs. However, since you mentioned mixed-language
with C++, I gather that it's not a real or simple option.
</digression>
Pozdrav,
--
Jugoslav
___________
www.xeffort.com
Please reply to the newsgroup.
You can find my real e-mail on my home page above.
thakns for your swift answer; unfortunately, I was off the line for a
while...
>
> Alas, Fortran 9x does not have "typedefs" for routine prototypes.
> You have to spell out entire prototype each time you need it.
> Thus, you may embed INTERFACE blocks recursively:
Your suggestion solved completely my previous problem.
> You may also take a look at EXTERNAL attribute. It may serve as
> a "light" INTERFACE block for your purpose, keeping the things
> simpler (esp. in the mixed-language environment) on the expense
Original problem has roots in "type safety" :)
Actually, we tried calling functions through pointers, and after
assigning pointer variables, we were able to call function directly, but
received bunch of runtime errors if we tried to use such pointer
variable as a actual parameter in function call.
Here is the (simplified) example that illustrates the problem:
we have 2 functions:
p1, (real function returning real)
euler, that calculates integral of dummy function f
we also have pointer variable fcn, initialized with function p1
If we call p1 through pointer variable fcn directly, everything work
correctly, but if we try to use that variable as a actual argument for
function euler, some kind of "protection fault error" is received when
the program is started.
Can you (or someone else) shed some light on a problem?
Here is the code (we tried with Compaq fortran 6.6):
real function p1(x)
real, intent(in) :: x
p1 = x
return
end
real function euler(xp,xk,dx,f)
implicit none
real, intent(in) :: xp
real, intent(in) :: xk
real, intent(in) :: dx
interface
real function f(x)
real, intent(in) :: x
end function
end interface
real x, y
y = 0.0
do x=xp, xk, dx
y = y + f(x)*dx
end do
euler = y
end
program main
implicit none
interface
real function p1 (x)
real, intent(in) :: x
end function
real function fcn (x)
real, intent(in) :: x
end function
real function euler (xp,xk,dx,f)
real, intent(in) :: xp, xk ,dx
interface
real function f(x)
real, intent(in) :: x
end function
end interface
end function
end interface
real x, xp, xk, dx, y
pointer (pfcn, fcn)
pfcn = loc(p1)
xp = 0.0
xk = 1.0
dx = 0.0005
!directly calling p1 through pointer variable fcn
y = 0.0
do x=xp, xk, dx
y = y + fcn(x)*dx
end do
print *,'integral f(x) u intervalu [0,1] = ', y
!trying to call p1 within euler
! does not work
y = euler(0.0,1.0,0.0005,fcn)
print *,'integral f(x) u intervalu [0,1] = ', y
stop
end
>
> Pozdrav,
Pozdrav,
:)
Yes. Your code just exposed bugs in two different compilers (of the same
lineage but different vintage) :-)).
As far as I can tell, the code is correct. POINTER to procedure is
Visual Fortran extension, not encountered in most other compilers.
However, with documented semantics and behavior, I'd say that your
code ought to work.
CVF goes berserk somewhere in the process, passing to euler something
other than address of the function P1. Didn't play too much with it
to tell you if a workaround exists; maybe Monday.
IVF 10.1.021 compiles and runs the code correctly UNLESS the (default)
/check-interfaces /gen-interfaces option is set.
(cross-check the routine prototypes even if implicit). When it's set,
it complains with an obscure error message at
y = y + fcn(x)*dx
Error: There is a conflict between local interface block and
external interface block.
Which, AFAICT,
http://softwarecommunity.intel.com/isn/Community/en-US/forums/thread/30238640.aspx
means that the INTERFACE and the actual prototype of <whatever> don't match...
except that everything matches however one looks at it.
<Steve should I report this to Premier or will you do Leclerc the honors? :-) >
once more, thanks for your swift answer,
have a nice weekend,
Gordan
And a third one of different lineage also fails: gfortran, which also
miscompiles it
(PR 36528). The program works using sunf95.
> y = y + fcn(x)*dx
> Error: There is a conflict between local interface block and
> external interface block.
This is similar to gfortran's failure, which fails at link time with
undefined reference to `fcn_'
> <Steve should I report this to Premier or will you do Leclerc the honors? :-) >
I missed this - and reported it now as i485792 (it still fails with
the latest ifort version).
Tobias
> y = y + fcn(x)*dx
> Error: There is a conflict between local interface block and
> external interface block.
>
> Which, AFAICT,
> http://softwarecommunity.intel.com/isn/Community/en-US/forums/thread/30238640.aspx
> means that the INTERFACE and the actual prototype of <whatever> don't match...
> except that everything matches however one looks at it.
>
> <Steve should I report this to Premier or will you do Leclerc the honors? :-) >
I will review the example and, if required, escalate the issue.
--
Steve Lionel
Developer Products Division
Intel Corporation
Nashua, NH
For email address, replace "invalid" with "com"
User communities for Intel Software Development Products
http://softwareforums.intel.com/
Intel Fortran Support
http://support.intel.com/support/performancetools/fortran
My Fortran blog
http://www.intel.com/software/drfortran
This should be f1 = x*20
> end