A CONTAINed procedure has access to all the variables in the host. Could the language be modified to allow access to only specified variables, as is the case when USEing a module? I’d like syntax like this to work:
subroutine foo(x1,x2)
contains
real, intent(in) :: x1,x2
subroutine bar()
use foo, only: x1 ! contained subroutine has access to x1 but not x2
end subroutine bar
end subroutine foo
1 Like
Fortran 2018 enhances IMPORT facility which helps precisely with situations mentioned here. The document proxy (18-007r1, section 8.8) for the standard provides details: Here’s an excerpt:
1 8.8 IMPORT statement
2 R867 import-stmt is IMPORT [[ :: ] import-name-list ]
3 or IMPORT, ONLY : import-name-list
4 or IMPORT, NONE
5 or IMPORT, ALL
6 C896 (R867) An IMPORT statement shall not appear in the scoping unit of a main-program, external
7 subprogram, module, or block-data.
Here’s a check with Intel oneAPI IFORT classic compiler (available to everyone for download) that works as expected:
module m
implicit none
contains
subroutine sub1( x1, x2 )
real, intent(in) :: x1, x2
call sub2()
contains
subroutine sub2()
import, only : x1 !<-- only x1 is imported from containing scope
print *, "x1 = ", x1, "; expected is 123.0"
print *, "x2 = ", x2 !<-- error because x2 not imported nor declared
end subroutine
end subroutine
end module
use m, only : sub1
real :: a, b
a = 123.0 ; b = -1.0
call sub1( a, b )
end
C:\Temp>ifort /c /standard-semantics /warn:all /stand:f18 p.f90
Intel(R) Fortran Intel(R) 64 Compiler Classic for applications running on Intel(R) 64, Version 2021.1 Build 20201112_000000
Copyright (C) 1985-2020 Intel Corporation. All rights reserved.
p.f90(11): error #6404: This name does not have a type, and must have an explicit type. [X2]
print *, "x2 = ", x2 !<-- error because x2 not imported nor declared
---------------------------^
5 Likes
Thanks. Does the latest gfortran have this feature? Compiling your code above with GNU Fortran (GCC) 11.0.0 20200927 from equation.com, excluding the “error line”, I get
p.f90:9:16:
9 | import, only : x1 !<-- only x1 is imported from containing scope
| 1
Error: IMPORT statement at (1) only permitted in an INTERFACE body
p.f90:15:8:
15 | use m, only : sub1
| 1
Fatal Error: Cannot open module file 'm.mod' for reading at (1): No such file or directory
compilation terminated.
I may end up learning Fortran beyond F95 by asking for feature X and being told that it’s already in Fortran 2018. But now I do see section “5.20 Control of host association” in The new features of Fortran 2018 and will reread that document.
If you declare a local variable in a contained procedure that has the same name as one in the host, access to the host variable is blocked.