I've recently learnt about interface blocks when adding a function to my Fortran program. Everything works nice and neatly, but now I want to add a second function into the interface block.
Here is my interface block:
interface function correctNeighLabel (A,i,j,k) integer :: correctNeighLabel integer, intent(in) :: i,j,k integer,dimension(:,:,:),intent(inout) :: A end function function correctNeighArray (B,d,e,f) character :: correctNeighArray integer, intent(in) :: d,e,f character, dimension(:,:,:),intent(inout) :: B end function end interface
It appears to me that this may not be the best option.
I've looked into subroutines, but I'm not very confident that it's the right solution. What I'm doing is relatively simple, and I need to pass arguments to the subroutine, but all the subroutines I've seen are a) complicated (i.e. too complicated for a function), and b) don't take arguments. They behave as though they manipulate variables without them being passed to them.
I've not really looked into modules properly, but from what I've seen it's not the right thing to use.
Which should I use when, and how do I go about it best?
Using a Module into your ProgramYou can add as many modules as needed, each will be in separate files and compiled separately. A module can be used in various different programs. A module can be used many times in the same program. The variables declared in a module specification part, are global to the module.
A function must return a single value, and can be invoked from within expressions, like a write statement, inside an if declaration if (function) then , etc. A subroutine does not return a value, but can return many values via its arguments and can only be used as a stand-alone command (using the keyword call ).
The subroutine call is an entire instruction. To call a function, use the function name (label or program member name) immediately followed by parentheses that can contain arguments. There can be no space between the function name and the left parentheses.
The 'USE' statement can be included in any program unit, function or subroutine of a Fortran 90 code. Its syntax can be described in two forms. 1.2.1 The simple 'USE' statement. USE <module name> This makes accessible all the available entities of the module, so every procedure or item of data.
Modules are always the right thing to use ;-)
If you have a very simple F90 program you can include functions and subroutines in the 'contains' block:
program simple implicit none integer :: x, y x = ... y = myfunc(x) contains function myfunc(x) result(y) implicit none integer, intent(in) :: x integer :: y ... end function myfunc end program
Then the interface of the functions/subroutines will be known in the program and don't need to be defined in an interface block.
For more complex programs you should keep all functions/subroutines in modules and load them when required. So you don't need to define interfaces, either:
module mymod implicit none private public :: myfunc contains function myfunc(x) result(y) implicit none integer, intent(in) :: x integer :: y ... end function myfunc end module mymod program advanced use mymod, only: myfunc implicit none integer :: x, y x = ... y = myfunc(x) end program advanced
The module and the program can (actually should) be in separate files, but the module has to be compiled before the actual program.
Seconding and extending what has already been said. It is better to put your procedures (subroutines and functions) into modules and "use" them because them you get automatic consistency checking of the interfaces with little effort. The other ways have drawbacks. If you define the interface with an interface block, then you have three things to maintain instead of two: the interface, the procedure itself and the call. If you make a change, then all three have to be modified to be consistent. If you use a module, only two have to be changed. A reason to use an interface block is if you don't have access to the source code (e.g., pre-compiled library) or the source code is in another language (e.g., you are using C code via the ISO C Binding).
The drawback to the "contains" approach is that contained procedures inherit all of the local variables of the parent program ... which is not very modular and can be very confusing if you forget this "feature".
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With