I got the following error. But I am not sure how to fix it. Could anyone please help me with this? $ gfortran -fimplicit-none -o ./main.exe main.f90 main.f90:16.16: call evalf (x, n, f) 1 Error: Explicit interface required for 'evalf' at (1): assumed-shape argument $ cat main.f90 program main implicit none integer, parameter :: n = 25 integer, parameter :: dp = kind(1.0d0) real(dp) :: f real(dp), allocatable :: x(:) integer :: i ! Allocate dynamic arrays allocate (x(n)) do 14 i=1, n x(i) = 3.0d0 14 continue call evalf (x, n, f) ! f=.25d0*( x(1)-1.d0 )**2 ! do 20 i=2, n ! f = f + (x(i)-x(i-1)**2)**2 ! 20 continue ! f = 4.d0*f end program subroutine evalf (x, n, f) implicit none integer, parameter :: dp = kind(1.0d0) real(dp), intent(in) :: x(:) integer, intent(in) :: n real(dp), intent(out) :: f integer :: i f=.25d0*( x(1)-1.d0 )**2 do 20 i=2, n f = f + (x(i)-x(i-1)**2)**2 20 continue f = 4.d0*f end subroutine Regards, Peng
![]() |
0 |
![]() |
> "Peng Yu" wrote in message > call evalf (x, n, f) 1 Error: Explicit interface required for 'evalf' at (1): assumed-shape argument > $ cat main.f90 ..... > real(dp), allocatable :: x(:) ..... > allocate (x(n)) ..... call evalf (x, n, f) ..... > end program > subroutine evalf (x, n, f) > implicit none > integer, parameter :: dp = kind(1.0d0) > real(dp), intent(in) :: x(:) > integer, intent(in) :: n > real(dp), intent(out) :: f As the message says, an assumed-shape argument requires an explicit interface. An array declared with (:) is assumed shape. There are 3 ways to get an explicit interface: 1. write an interface block - Don't do this. 2. make the subroutine an internal procedure - put it after a contains statement within the main proram. 3. put the subroutine in a module - If you want to compile as one source file, put the code for the module before the main program. ---- e
![]() |
0 |
![]() |
Peng Yu <pengyu.ut@gmail.com> wrote: > I got the following error. But I am not sure how to fix it. Could anyone > please help me with this? (As an aside, I note that unlike the code mentioned in your previous thread that I responded to, which looked mostly like f77 with minor f90 features, this one is quite heavy in f90-isms. I also see that you do have access to an f90/f95 compiler). > call evalf (x, n, f) > 1 > Error: Explicit interface required for 'evalf' at (1): assumed-shape argument In f77 and before, each procedure in a program could always be compiled completely independently from every other procedure. That is you could always call a subroutine without telling the compiler anything about it. (For a function, you needed to tell the compiler the result type, but nothing else). The form of the subroutine call (or function reference) told the compiler everything it needed to know in order to compile the call (or function reference) correctly. This was called implicit interface because the information about the procedure's interface was implicit in the form of the call. Fortran 90 introduced many features relating to procedure arguments, and most of those features required that the calling procedure know things about the procedure that are not evident just from the form of the call. One of those features is assumed-shape arguments, as in your > subroutine evalf (x, n, f) .... > real(dp), intent(in) :: x(:) The (:) in the declaration of x here means that the compiler takes care of passing information about the shape of x to the subroutine. That's handy, but it does mean that the compiler must know to do this when compiling the call to this subroutine. This is not evident from the CALL statement alone. So the compiler must have information about the subroutine's dummy arguments. This information is called an explicit interface, as opposed to the implicit interface of all f77 subroutines. It is explicit because you have to explicitly tell the compiler this information instead of counting on it to infer the information from the call statement. Explicit interfaces are required to use most of the f90 features relating to procedure arguments, but they are useful even in cases where they are not required. In particular, they help the compiler catch many common errors. I recommend using explicit interfaces with almost all procedures in modern Fortran code. In addition to the benefits of improved error diagnosis, if you make it a habit to use explicit interfaces everywhere, then you won't need to bother with learning the exact rules on where they are required. There are 3 ways to provide an explicit interface. 1. The most recommended way is usually to put the subroutine in a module. There can be some fine points of this, but the simplest version looks something like module some_module_name contains ... your subroutine goes here. The whole thing, including its subroutine and end subroutine statements. end module some_module_name Then in whatever code that calls the subroutine, before any declarations, but after the recommended implicit none, add a USE statement for the module, as in use some_module_name The usual implementation of what happens here is that when you compile the module, the compiler automatically generates a file that has the information necessary to use the things in this module. In particular, this file includes the needed interface information for procedures in the module. You previously mentioned being familloiar with C. Although the analogy isn't perfect, you could think of this file as somewhat like a C include file with function prototypes, except that the file is automatically generated. The USE statement then tells the compiler to look for that file of information when compiling the calling code. 2. You can make the subroutine an internal subroutine to whatever calls it. This doesn't require quite as much "fuss" as putting the subroutine in a module, but it tends to have pretty limitted applicability. In some ways, it is the simplest approach if it happens to fit your need, but it doesn't fit a lot of needs. Like the module approach, the generation of the interface information is automatic. To do that put a CONTAINS statement (just that word - nothing else) right before the end statement of the calling procedure and then put the entire code of the called subroutine after that CONTAINS statement. 3. You can write an interface body for the procedure. This is usually the *LEAST* recommended approach. It is a bit laborious and error prone. Unfortunately, some people get confused by the terminology and think that when they are told they need an explicit interface, that means they need such an interface body. But an interface body is only one of the three ways to provide an explicit interface. One admited advantage of using an interface body is that it can be done without touching the code of the subroutine. The subroutine doesn't even have to be written in Fortran. Most of the interface bodies I write are for C functions called by my Fortran code. To write an interface body in the calling procedure, do interface .. code excerpted from your subroutine goes here. Include the subroutine statement, the end subroutine statement, and all the declarations relating to the subroutine dummy arguments. Do not include any executable statements (well, technically the end subroutine statement is executable, but that's a special case). end interface -- Richard Maine email: last name at domain . net dimnain: summer-triangle
![]() |
0 |
![]() |
"Richard Maine" wrote in message news:1m51orp.oje9a3hnmrk6N%nospam@see.signature... Beautiful discussion about the need for explicit interface, but the bullet points below missed proofreading: > There are 3 ways to provide an explicit interface. > 1. The most recommended way is usually to put the subroutine in a > module. There can be some fine points of this, but the simplest version > looks something like > module some_module_name > contains > ... your subroutine goes here. The whole thing, including > its subroutine and end subroutine statements. > end module some_module_name > Then in whatever code that calls the subroutine, before any > declarations, but after the recommended implicit none, add a USE > statement for the module, as in > use some_module_name In the above paragraph, USE goes before IMPLICIT NONE of course (10-007.pdf, table 2.1). > The usual implementation of what happens here is that when you compile > the module, the compiler automatically generates a file that has the > information necessary to use the things in this module. In particular, > this file includes the needed interface information for procedures in > the module. > You previously mentioned being familloiar with C. Although the analogy > isn't perfect, you could think of this file as somewhat like a C include > file with function prototypes, except that the file is automatically > generated. > The USE statement then tells the compiler to look for that file of > information when compiling the calling code. > 2. You can make the subroutine an internal subroutine to whatever calls > it. This doesn't require quite as much "fuss" as putting the subroutine > in a module, but it tends to have pretty limitted applicability. In some > ways, it is the simplest approach if it happens to fit your need, but it > doesn't fit a lot of needs. Like the module approach, the generation of > the interface information is automatic. To do that put a CONTAINS > statement (just that word - nothing else) right before the end statement > of the calling procedure and then put the entire code of the called > subroutine after that CONTAINS statement. > 3. You can write an interface body for the procedure. This is usually > the *LEAST* recommended approach. It is a bit laborious and error prone. > Unfortunately, some people get confused by the terminology and think > that when they are told they need an explicit interface, that means they > need such an interface body. But an interface body is only one of the > three ways to provide an explicit interface. One admited advantage of > using an interface body is that it can be done without touching the code > of the subroutine. The subroutine doesn't even have to be written in > Fortran. Most of the interface bodies I write are for C functions called > by my Fortran code. To write an interface body in the calling procedure, > do > interface > .. code excerpted from your subroutine goes here. Include the > subroutine statement, the end subroutine statement, and > all the declarations relating to the subroutine dummy arguments. > Do not include any executable statements (well, technically > the end subroutine statement is executable, but that's a special > case). > end interface 4. The interface to a RECURSIVE subroutine or a RECURSIVE function with a RESULT clause is explicit within the procedure. 5. Explicit interfaces may be cloned in a procedure declaration statement.
![]() |
0 |
![]() |
James Van Buskirk <not_valid@comcast.net> wrote: > "Richard Maine" wrote in message > news:1m51orp.oje9a3hnmrk6N%nospam@see.signature... > > Beautiful discussion about the need for explicit interface, but the > bullet points below missed proofreading: .... Thank you for the corrections. -- Richard Maine email: last name at domain . net dimnain: summer-triangle
![]() |
0 |
![]() |