I am writing a code and I want to reuse a lot of subroutines I wrote
in these years. Some of them use assumed-shape or even allocatable
array arguments, so I need explicit interfaces. What is the best way,
in your opinion, to provide an explicit interface for a subroutine?
Putting it into a module, or writing a module containing all the
interface blocks of the subroutines used by my main code, and USEing
that module?
Cheers,
deltaquattro
If you put them in a module, you do not need to maintain separate
interface blocks. These always impose the risk of getting out of
sync with the actual code.
So: definitely put them in a module (or several, as the case
may be)!
(You may want to use the INCLUDE directive, if the files get
too large)
Regards,
Arjen
Hi, Arjen,
"several" is most likely to be the case, because mine are mostly
unrelated subroutines, so prefer to keep the files separate and
immediately know what they do by just looking at the filenames,
instead that putting all of them in a big, "obscure" module. That's
the way I used to code when I first learned F90. For example, I would
often write:
(file linint.f90)
module linint_m
implicit none
contains
real function linint(x,x1,y1,x2,y2)
real,intent(in) :: x,x1,y1,x2,y2
linint = y1 + (y2-y1)/(x2-x1) * (x-x1)
end function linint
end module linint_m
Today this seems a bit redundant to me, because I then need to have a
lot of separate USE statements in my main code. But probably you're
right and that's Good Coding Style®.
>
> (You may want to use the INCLUDE directive, if the files get
> too large)
>
Mine are small utility subroutines/functions, so that's not likely to
be the case, unless I failed to understand your suggestion.
> Regards,
>
> Arjen
Best Regards,
deltaquattro
Let me elaborate:
With INCLUDE directives you can keep the code in separate
files and have the compiler put all program text together.
Like this:
module my_gigantic_collection
contains
include "linint.f90"
include "quadint.f90"
include "cubint.f90"
...
end module
The only caveat is that each included file must be set up so that
inserting the contents into the above (replacing the line with
"include ...") results in valid code.
One thing to watch out for:
subroutine ...
... code ...
end
won't work - you need to use "end subroutine" or the like to
make it perfectly clear that the end of the subroutine is
meant, not the end of the module.
Regards,
Arjen
>
> With INCLUDE directives you can keep the code in separate
> files and have the compiler put all program text together.
> Like this:
>
> module my_gigantic_collection
>
> contains
>
> include "linint.f90"
> include "quadint.f90"
> include "cubint.f90"
> ...
>
> end module
>
Good idea: this definitely defeats the need for an interface block
module. Your "include" module gives the same results (explicit
interfaces for all subroutines used by a main code with just one USE
statement) without the risk of mismatch between interface blocks and
subroutine arguments lists.
> The only caveat is that each included file must be set up so that
> inserting the contents into the above (replacing the line with
> "include ...") results in valid code.
Ok.
>
> One thing to watch out for:
>
> subroutine ...
> ... code ...
>
> end
>
> won't work - you need to use "end subroutine" or the like to
> make it perfectly clear that the end of the subroutine is
> meant, not the end of the module.
That's not a problem since I've always used "end subroutine". What I
must not do, instead, is changing my subroutines into modules, like I
showed in my second post, because a module cannot CONTAIN another
module. So in the end your suggestion is: don't change the subroutines
into modules, just write an "include" module for my main code and USE
it. Ok, thanks,
Cheers
deltaquattro
> "several" is most likely to be the case, because mine are mostly
> unrelated subroutines, so prefer to keep the files separate and
> immediately know what they do by just looking at the filenames,
> instead that putting all of them in a big, "obscure" module.
I would be suprised if there wasn't *SOME* kind of sensible
categorization of the routines that worked well. I would suspect that
something makes sense in between the "one big module with everything"
versus "each routine in it's own module".
But I'm at a loss to describe how to come up with such an organization.
That's something that comes fairly natually to me in terms of doing it,
but I'm not sure how to teach it.
--
Richard Maine | Good judgment comes from experience;
email: last name at domain . net | experience comes from bad judgment.
domain: summertriangle | -- Mark Twain