Do I need to put implicit none
inside every function and subroutine?
Or is it enough to put it at the beginning of the module containing these functions and subroutines?
Or is it enough to put it at the beginning of the program that is using these modules?
From observation of other's working code, implicit none
is included in all these places. I am not sure if this is done redundantly because removing implicit none
from subroutines still compiled and produced the same output.
By the way, I am using gfortran fortran 90
.
No, Yes (sort of) and No.
Once per program unit (which is not the same thing as once per program) and in each interface body is enough.
A program unit is either a main program, a module, an external subprogram (a function or a subroutine subprogram that does not appear after the CONTAINS statement of another type of program unit), a block data program unit or a submodule. Unless specified otherwise with an IMPLICIT statement, the default in each program unit is the default mapping of things starting with I-N as default integer and everything else as default real.
The same principle applies to interface bodies - as they are supposed to be a snapshot of the specification part of a procedure defined in another program unit. That other program unit would have the default mapping unless otherwise specified differently, so the interface body has the default mapping unless otherwise specified differently.
Inside a program unit, internal subprograms or module subprograms inherit whatever implicit typing is specified in their host, in the absence of a "local" IMPLICIT statement within the subprogram proper.
Redundant specification of IMPLICIT NONE is harmless. You often see it where subprograms that were formerly external subprograms have been put into a module.
If you are using
gfortran
, you may as well simply add an-fimplicit-none
parameter.Note that this is a compiler-specific solution. Other widespread compilers may not support this parameter. For example, Intel's
ifort
ignores this as an unknown option.Here is an informal answer based on what works for me.
My Fortran code is in two types of files -- those containing a main program and those containing a single module. In each kind of file, IMPLICIT NONE appears just after the "program foo" or "module foo" statements and after the USE statements at the top. It does not appear within subroutines or functions, because that would be redundant.
The
implicit
statement (includingimplicit none
) applies to a scoping unit. Such a thing is defined asThis "excluding all nested scoping units in it" suggests that it may be necessary/desirable to have
implicit none
in each function and subroutine (collectively, procedures) defined in a module. However, inside procedures contained within a module there is a default mapping based on the host scoping unit. So, withimplicit none
in the module it isn't necessary to have that in contained procedures.This host scoping unit rule applies equally to internal programs. This means that
implicit none
in the main program covers all procedures contained in it; and that the same applies for internal programs of module procedures. Block constructs see this also, and theimplicit
statement isn't even allowed within one of these.However, external functions/subroutines will not inherit implicit behaviour from a program or module, and modules don't inherit it from programs/other modules which
use
them. This clearly makes sense as the implicit typing must be known at compile time and be well defined regardless of their ultimate use.Further, one cannot do
An
implicit
statement must follow alluse
statements.This host scoping unit rule notably doesn't apply to interface bodies. IanH's answer motivates that exception, but it's an important enough thing to re-stress. It has caused much confusion.
Regarding the test of removing
implicit none
from a subroutine: if the code is valid withimplicit none
then it must be valid and identical without that statement. All entities must be explicitly declared in the former case, so no implicit rules would be applied in the latter.