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

Array constructor strange behavior

s8000_1
Beginner
827 Views
Hi!
When i use array constructor following problem appears (example). I wrote some comments there.

! file f1.f90
PROGRAM Main
USE MyModule
IMPLICIT NONE
REAL,DIMENSION(0:3):: x
CALL TestFN(myFN,x)
END PROGRAM Main

! file f2.f90
MODULE MyModule
IMPLICIT NONE
CONTAINS
SUBROUTINE TestFN(myFN,x)
REAL,EXTERNAL :: myFN
REAL,DIMENSION(0:),INTENT(OUT) :: x
INTEGER i
x=[(myFN(i),i=0,UBOUND(x,DIM=1))]
END SUBROUTINE TestFN

REAL FUNCTION myFN(x,param)
REAL,INTENT(IN) :: x
REAL,INTENT(IN),OPTIONAL :: param
PRINT*,PRESENT(param)
!here is a trouble
!actually "param" is not PRESENT
!but on the first step
!it is .TRUE.
!after printing this function there is
!TFFF, but must be FFFF
myFN=x
END FUNCTION myFN
END MODULE MyModule

Is it a bug of array constructor? (Version 9.1.3291)
0 Kudos
7 Replies
Steven_L_Intel1
Employee
827 Views
No, it's your bug, but very understandable. In TestFN, when you declared the passed argument myFN as EXTERNAL, that means it has an implicit interface. But the routine you're actually calling, the module procedure myFN, requires an explicit interface because it has an OPTIONAL argument.

The solution is to replace:

REAL,EXTERNAL :: myFN

with:

INTERFACE
REAL FUNCTION myFN(x,param)
REAL,INTENT(IN) :: x
REAL,INTENT(IN),OPTIONAL :: param
END FUNCTION myFN
END INTERFACE
0 Kudos
s8000_1
Beginner
827 Views
BIG thanks for solution of my problem! :)
0 Kudos
s8000_1
Beginner
827 Views
And how can i make "assumed-shape" interface?
I mean calling external functions with different interfaces.
For example:

SUBROUTINE TestFN(FN,x)
...
x=[(FN(i),i=0,UBOUND(x,DIM=1))]
...
END SUBROUTINE TestFN

REAL FUNCTION myFN(x,param)
INTEGER,INTENT(IN) :: x
REAL,INTENT(IN),OPTIONAL :: param
...
END FUNCTION myFN

REAL FUNCTION myFN1(x)
INTEGER,INTENT(IN) :: x
...
END FUNCTION myFN

And i want to call TestFN with functions myFN,myFN1 as arguments.
Is there any other way, except making "pseudo" argument "param" in myFN1?

0 Kudos
Steven_L_Intel1
Employee
827 Views
The only way I can think of to do this sort of thing is to have a set of intermediate "call it" routines, one for each signature. When you pass the routine to the first routine, it declares it as EXTERNAL and then calls an appropriate second routine, passing the argument along. Each second routine declares the argument with the correct interface and then calls.

This is all very complicated and error-prone. What exactly are you trying to accomplish here? Perhaps there's a better way.
0 Kudos
s8000_1
Beginner
827 Views
heh... really complicated...

I would like to make a subroutine SOLVE(outfuncition,equation,startmeanings,method)
where "method" is external subroutine. Every method has it's own interface but with one common argument "x", other arguments differ from each other. Think to make other arguments except "x" OPTIONAL and make one interface for all methods (in which i will declare unused optional arguments). The task of making such subroutine is because i solve only small part of big calculation problem. =
0 Kudos
Steven_L_Intel1
Employee
827 Views
I suggest not using OPTIONAL or anything that would require an explicit interface. Use some other method to determine whether or not arguments are present.
0 Kudos
s8000_1
Beginner
827 Views
I will try to think out something. Thanks for consultation, Steve! :)
0 Kudos
Reply