让我们说有一个向量:
REAL(KIND=dp), DIMENSION(maxn) :: rho
在初始子程序(以及dp
和maxn
)中分配值,并从主程序中调用。
主程序然后调用一个包含(不同的)子程序的模块来进化rho
。 rho
的子例程参数定义为:
SUBROUTINE sum_density(a, b, c, ....., rho)
在这个子程序中,rho被声明为:
REAL(KIND=dp), DIMENSION(maxn), INTENT(OUT) :: rho
然而,在与rho
:
foo1= foo2*foo3(i)/rho(i)
我原以为模块子程序无法访问主程序中定义的rho
。我期望编译器抱怨并要求将意图更改为(INOUT)
或者说rho
之类的内容未定义。即使我将其更改为(INOUT)
,结果也没有差异。模块子例程必须访问主程序中rho
的值并使用它,即使意图声明为OUT
。
我的问题是 - 在这种情况下,使用INTENT(OUT)
和INTENT(INOUT)
之间的区别是什么?
答案 0 :(得分:3)
使用INTENT(OUT)
程序不符合标准,因为它访问具有未定义值的数组。
然而,由于通常实现显式形状数组的方式 - 通过传递数组的地址,软件实现可能会起作用。如果您传递的数组不连续,请说
rho(::2)
编译器可能会创建一个副本,该副本会被传递并且您可能会遇到问题,因为该数组可能包含intent(out)
的垃圾。
关于警告,它们不是强制性的,但如果您使用-warn
或-Wall
等标记,编制者会对此发出警告。
对于intent(in)
,当您尝试修改rho
时会出现差异。如果您尝试编译器必须发出错误。
关于范围:
在这里讨论范围并不正确,原始rho
绝对不在子程序的范围内,只有伪参数。重复使用相同名称可能会令人困惑。想象一下,它们实际上在程序中被称为rho1
,在子程序中被称为rho2
。然后很明显rho1
不在子程序的范围内,但是rho2
是。
现在,rho2
不能保证在rho1
的子例程开头与intent(out)
具有相同的值,但保证intent(inout)
与intent(out)
保持一致。原因是可以使用copy-in和copy-out实现参数传递,并且module m
contains
subroutine sub(a2)
real, intent(out) :: a2(4)
print *,a2
a2 = 2
end subroutine
end
use m
real :: a1(8)
a1 = 1
call sub(a1(::2))
end
可以省略复制。
考虑以下代码:
sunf90 intent2.f90
./a.out
5.879759E-39 0.0E+0 0.0E+0 0.0E+0
对于某些编译器,它会打印4次,正如人们所预料的那样,但是对于其他编译器参数,它会打印垃圾:
{{1}}