Ifort compiler doesn't recognize interface in Fortran - interface

When I try to compile code under the statement with ifort it returns error as:
error #8169: The specified interface is not declare
But it works perfectly on gfortran, for some reason I have to use intel compiler to compile this work. The language I am using is Fortran. The reason for this is that the 'ifort' compiler does not see the variables in Interface. So I develop a module called Var to do fix that. And Use it in every blocks. But it returns error:
This USE statement is not positioned correctly within the scoping unit.
The var module is like following:
MODULE VAR
CHARACTER(50) :: callbackID
END MODULE
how can I fix the problem thanks alot! My compiler version is ifort 12.1.0
MODULE DEMO
USE VAR
INTERFACE
SUBROUTINE callback_prototype(callbackID)
USE VAR
CHARACTER(*) :: callbackID
END SUBROUTINE callback_prototype
END INTERFACE
PROCEDURE( callback_prototype ), POINTER :: f_ptr => NULL()
CONTAINS
SUBROUTINE set_callback(func)
IMPLICIT NONE
EXTERNAL :: func
f_ptr => func
call HELLO
END SUBROUTINE
SUBROUTINE invoke_callback(callbackID)
CHARACTER(*) :: callbackID
if (associated(f_ptr)) call f_ptr(callbackID)
END SUBROUTINE
SUBROUTINE HELLO
IMPLICIT NONE
!dosomthing
END SUBROUTINE
END MODULE

The code as presented is not legal fortran. The use statement inside the interface body makes accessible a name that is the same as a dummy argument. This violates the scoping rules of the language.
The use statement inside the interface body would appear to be superfluous.

I don't see the reason why you want the use statement in the interface in the first place. Even the interface can be skipped, because you have the right procedure accessible:
PROCEDURE( invoke_callback ), POINTER :: f_ptr => NULL()

Related

Fortran polymorphism in pointers

I am trying to use pointers to create links between objects. Using Fortran and here is the code piece:
module base_pars_module
type,abstract,public :: base_pars
end type
end module
module test_parameters_module
use base_pars_module
type, extends(base_pars) :: test_pars
contains
procedure :: whoami
end type
contains
function whoami(this) result(iostat)
class( test_pars) :: this
write(*,*) 'i am a derived type child of base_pars'
end type
end module
module base_mask_module
use base_pars module
type, abstract , public :: base_mask
class(base_pars),pointer :: parameters
end type
end module
module test_mask_module
use base_mask_module
implicit none
type, extends(base_mask) :: test_mask
end type
end module
program driver
type(test_pars) , target :: par_Test
type(test_mask) :: mask_test
iostat= par_test%whoami()
mask_test%parameters=>par_test
iostat=mask_test%parameters%whoami()
end program
parameters at base_mask_module is a pointer with base_pars class. I would like to use this pointer to refer par_test object which is test_pars type that extends base_pars type. So the pointer and the target has the same class. But when I compile this it gives an error:
driver.f90:17.37:
iostat=mask_test%parameters%whoami()
1
Error: 'whoami' at (1) is not a member of the 'base_pars' structure
Is it a bug or am i doing something wrong?
When you have polymorphism like this there are two things to consider about an object: its dynamic type and its declared type. The parameters component of test_mask (base_mask) is declared as
class(base_pars),pointer :: parameters
Such a component therefore has declared type base_pars.
Come the pointer assignment
mask_test%parameters=>par_test
mask_test%parameters has dynamic type the same as par_test: test_pars. It's of declared type base_pars, though, and it's the declared type that is important when we care about its components and bindings. base_pars indeed has no whoami.
You need, then, something which has declared type par_test. Without changing the definitions of the derived types you can do this with the select type construct.
select type (pars => mask_test%parameters)
class is (par_test)
iostat=pars%whoami() ! pars of declared type par_test associated with mask_test%parameters
end select
That said, things get pretty tedious quite quickly with this approach. Always using select type, distinguishing between numerous extending types, will be quite a bind. An alternative would be to ensure that the declared type base_pars has a binding whoami. Instead of changing the main program as above, we alter the module base_pars_module:
module base_par_modules
implicit none ! Encourage good practice
type,abstract,public :: base_pars
contains
procedure(whoami_if), deferred :: whoami
end type
interface
integer function whoami_if(this)
import base_pars ! Recall we're in a different scope from the module
class(base_pars) this
end function
end interface
end module
So, we've a deferred binding in base_pars that is later over-ridden by a binding in the extending type test_pars. mask_test%parameters%whoami() in the main program is then a valid and the function called is that offered by the dynamic type of parameters.
Both approaches here address the problem with the binding of the declared type of parameters. Which best suits your real-world problem depends on your overall design.
If you know that your hierarchy of types will all have enough in common with the base type (that is, all will offer a whoami binding) then it makes sense to go for this second approach. Use the first approach rather when you have odd special cases, which I'd suggest should be rare.

what is the correct way to write a specific interface in fortran?

I tried the following code to get the code to work correctly. It seems I need to write an interface to avoid mistaken results. I wrote the following, but it does not pass the compiling stage. The errors are the following: (use gfortran compiler)
fit.f90:34.16:
TYPE(spec), INTENT(IN) :: SMP
1
Error: Derived type 'spec' at (1) is being used before it is defined
fit.f90:35.12:
REAL(q), INTENT(OUT) :: RES
1
Error: Symbol 'q' at 1 has no IMPLICIT type
...
Here is the compilable code to illustrate the issue.
MODULE prec
INTEGER, PARAMETER :: q=8
END MODULE prec
MODULE MOD_FIT
USE prec
INTEGER, PARAMETER :: NO_NI=200
TYPE spec
! source of fitting
INTEGER NW
COMPLEX(q), POINTER :: W(:),G(:)
! how spectrum is parametrized
INTEGER NO_NM ! continuous points labeled as 1,2,3,...,NO_NM
REAL(q), ALLOCATABLE :: O_N(:),O_D(:) ! frequency
REAL(q), POINTER :: A_N(:),B_N(:),A_D(:) ! A(Omega)
END TYPE
TYPE(spec) SMP
INTERFACE
SUBROUTINE NNLS_CMPLX(SMP,RES,RES_V)
IMPLICIT NONE
TYPE(spec), INTENT(IN) :: SMP
REAL(q), INTENT(OUT) :: RES
COMPLEX(q), OPTIONAL, INTENT(OUT) :: RES_V(SMP%HN)
END SUBROUTINE NNLS_CMPLX
END INTERFACE
CONTAINS
SUBROUTINE NNLS_CMPLX(SMP,RES,RES_V)
IMPLICIT NONE
TYPE(spec) :: SMP
REAL(q) :: RES
COMPLEX(q), OPTIONAL :: RES_V(*)
RES=0
IF(PRESENT(RES_V)) RES_V(1)=0
END SUBROUTINE NNLS_CMPLX
END MODULE MOD_FIT
PROGRAM MAIN
USE prec; USE MOD_FIT
REAL(q) PK_RES
COMPLEX(q) RES_V(4)
CALL NNLS_CMPLX(SMP,PK_RES,RES_V)
END
Having an explicit interface means that the compiler knows how the called subroutine or function (procedure) looks like.
Explicit interfaces should not be normally provided by an interface block, that is the thing:
interface
...
end interface
but by placing the procedures in modules instead.
You definitely cannot use an interface block for a module procedure (a procedure placed inside a module). Interface block tells that there is some external procedure somewhere with the properties you declare in the interface block. But your procedure is not external, it is in a module.
Just remove the interface block and it should work.
Just a suggestion: use small caps and indentation in your code. It is very difficult to read as it stands.
To explain the actual error message: As francescalus comments, interface blocks have a separate scope. If they are placed in a module, they do not see the other contents of the module. That's why the compiler complains it does not know what spec and q are.

Make external callback function accessible to other routines in Fortran (LF95)

I have a very similar problem to the one described here: Make external functions accessible for other functions/modules in Fortran
I'm working with a DLL compiled from Fortran source code, using the Lahey/Fujitsu LF95 compiler and I'm trying to store a global reference to an external callback function (function pointer) so that it can be called at a later time from other functions in the Fortran DLL.
The scenario is something like this:
the host application invokes a subroutine (procedure) from the Fortran DLL and passes a reference to the callback function
a reference to the callback function should be stored as a global
later, the host application may call various functions from the Fortran DLL and these functions need to invoke the callback function, calling into the host application.
The problem is that the accepted answer from the question doesn't compile with the Lahey Fortran compiler. Apparently, there are quite some differences between the Intel compiler and the LF95 compiler.
I did get the callback reference to work fine in a single subroutine, like this:
subroutine testcallback(cbk)
dll_export :: testcallback ! Lahey LF95 extern declaration to export this function
character(len=*) :: text
interface
subroutine cbk (string, length)
character(len=*), intent (in) :: string
integer, intent (in) :: length
end subroutine cbk
end interface
text = "Hello World"
call cbk(text, len(text)) ! invoke the cbk callback; works very well
return
end
Invoking this function from the host application (C# in my case but that's inconsequential) works very well. I can pass in a function reference (delegatae in C#) and Fortran makes the call correctly and I get the expected results.
The issue is that I can't seem to be able to move the interface declaration outside of testcallback, and then subsequently call the cbk from a different Fortran function.
Here's an example of what I would want to accomplish:
subroutine setcallback(cbk)
dll_export :: setcallback ! Lahey LF95 extern declaration to export this function
interface
subroutine cbk (string, length)
character(len=*), intent (in) :: string
integer, intent (in) :: length
end subroutine cbk
end interface
! instead of calling cbk here, I'd like to save a reference to it and make it
! available to other functions..
return
end
subroutine testcallback()
dll_export :: testcallback ! Lahey LF95 extern declaration to export this function
character(len=*) :: text
text = "Hello World Again"
! somehow I want to be able to invoke the stored reference to cbk here
!
call cbk(text, len(text)) ! this obviously doesn't work like this
return
end
In closing I'd like to add that moving away from the LF95 compiler is not an option at this time. If anybody knows how to handle this I would very much appreciate it!

How to use a user-defined-type in a Fortran interface

In a Fortran 2003 module I'm defining a type called t_savepoint and, later, I want to define an interface for a subroutine called fs_initializesavepoint, which takes an object of type t_savepoint as only argument.
Here is the code for the whole module:
module m_serialization
implicit none
type :: t_savepoint
integer :: savepoint_index
real :: savepoint_value
end type t_savepoint
interface
subroutine fs_initializesavepoint(savepoint)
type(t_savepoint) :: savepoint
end subroutine fs_initializesavepoint
end interface
end module m_serialization
The reason why I want such an interface is that later on I will make this fortran module interoperate with C.
If I try to compile it (gfortran-4.7.0), I get the following error message:
type(t_savepoint) :: savepoint
1
Error: The type of 'savepoint' at (1) has not been declared within the interface
The error disappears if I move the definition of the type inside the subroutine; but if then I want to use the same type within many subroutines, should I repeat the definition in all of them?
Thank you in advance.
EDIT: a solution would be to move the definition of the type onto another module and then to use it in every subroutine. However I don't like this solution too much, because the type t_savepoint and the subroutines are part of the same conceptual topic.
Rightly or wrongly in an interface block you don't have access to the environment by host association. To fix this you need to import the datatype exlicitly:
[luser#cromer stackoverflow]$ cat type.f90
module m_serialization
implicit none
type :: t_savepoint
integer :: savepoint_index
real :: savepoint_value
end type t_savepoint
interface
subroutine fs_initializesavepoint(savepoint)
Import :: t_savepoint
type(t_savepoint) :: savepoint
end subroutine fs_initializesavepoint
end interface
end module m_serialization
[luser#cromer stackoverflow]$ gfortran -c type.f90
This is f2003.
However I suspect the way you have put this suggests you are not going about coding this up the best way. Better is simply to put the routine itself in the module. Then you don't need bother with the interface at all:
module m_serialization
implicit none
type :: t_savepoint
integer :: savepoint_index
real :: savepoint_value
end type t_savepoint
Contains
Subroutine fs_initializesavepoint(savepoint)
type(t_savepoint) :: savepoint
Write( *, * ) savepoint%savepoint_index, savepoint%savepoint_value
End Subroutine fs_initializesavepoint
end module m_serialization
[luser#cromer stackoverflow]$ gfortran -c type.f90
Given that modules are really designed to deal with connected entities this is really the way to do it in Fortran. It also has the advantage of only requiring a f95 compiler, so is universally available (though admittedly import is commonly implemented)

Doxygen and Fortran with KIND parameters

I'm using Doxygen to document a Fortran code and I have variables declared such as:
REAL(KIND=8), PARAMETER :: myParam = 1.0_8
but Doxygen gets confused and seems to think REAL is a function and throws:
warning: documented function `real' was not declared or defined.
I have OPTIMIZE_FOR_FORTRAN set to YES so that's not the issue.
Is there a way to rectify this without having to wrap some pre-processor guard around my variables to declare them as REAL without the KIND parameter when building documentation?