Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

function declaration problem, with 'implicit none'

1 view
Skip to first unread message

gordan...@gmail.com

unread,
Jun 10, 2008, 4:19:47 AM6/10/08
to
Hello,

\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

Jugoslav Dujic

unread,
Jun 10, 2008, 4:46:27 AM6/10/08
to
gordan...@gmail.com wrote:
| Hello,
|
| \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.

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.

Leclerc

unread,
Jun 13, 2008, 7:55:15 AM6/13/08
to
Hi Jugoslav,

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,
:)

Jugoslav Dujic

unread,
Jun 13, 2008, 8:33:53 AM6/13/08
to
<snip code>

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? :-) >

Leclerc

unread,
Jun 13, 2008, 8:50:55 AM6/13/08
to
Hi,

once more, thanks for your swift answer,

have a nice weekend,

Gordan

Tobias Burnus

unread,
Jun 13, 2008, 10:41:19 AM6/13/08
to
On Jun 13, 2:33 pm, "Jugoslav Dujic" <jdu...@yahoo.com> wrote:
> Yes. Your code just exposed bugs in two different compilers (of the same
> lineage but different vintage) :-)).

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

Steve Lionel

unread,
Jun 13, 2008, 3:45:50 PM6/13/08
to
Jugoslav Dujic wrote:

> 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

robin

unread,
Jun 13, 2008, 8:59:56 PM6/13/08
to
<gordan...@gmail.com> wrote in message
news:9dae66a9-a81f-40a0...@34g2000hsf.googlegroups.com...
> Hello,

>
> 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

This should be f1 = x*20

> end


0 new messages