intent(out)和intent(inout)的区别

13

根据Fortran标准:

对于非指针虚参,INTENT (OUT)属性指定该虚参在调用过程中变为未定义

然而,这段简单的代码却输出了5,因此似乎在开始执行该过程(在本例中为子例程)时,该实参并没有变为未定义状态。

subroutine useless(a)
  integer, intent(out) :: a
  print *,a
end subroutine useless

program test
  integer :: n=5
  call useless(n)
end program test

我错在哪里了?intent(inout)intent(out)似乎是一样的。


1
有趣的是,gfortran和ifort都打印出5,尽管ifort警告一个具有显式INTENT(OUT)声明的虚拟参数没有给出显式值 - Raul Laasner
@Ross,你可能在重新标记方面是正确的,但是有很多类似的问题存在...如果你想做很多这样的编辑,最好等到可以无需审核进行编辑。我经常只是保留[tag:fortran90],即使添加了通用标签,以确保不改变OP的意图。 - Vladimir F Героям слава
1个回答

14

intent(inout)intent(out)显然不同。你指出了原因,但没有得出正确的结论。进入子程序useless时,a是未定义的,而不是已定义的。

变量“未定义”意味着在引用它时不能依赖于特定的行为。你观察到变量a具有值5,但这并不意味着你只能观察到5。特别是,“未定义”不意味着“像NaN那样具有特定的值”。

由于引用了未定义的变量,你的代码不符合标准。请参阅Fortran 2008 6.2(与最初标记的Fortran 90中的类似含义)。特别要注意的是编译器不必指出你的错误。

使用intent(inout)时,在引用变量a时会被定义,并且保证具有值5(对于符合处理器的情况)。

更广泛地说,两个意图属性之间还有其他差异,变量a的定义相似可能会更麻烦。

例如,可分配数组和具有延迟类型参数的对象将被取消分配;派生类型变为未定义(和任何可分配组件都被取消分配),具有默认初始化的组件被“重新初始化”;指针的关联状态变得未定义。

所有这些后者的事情都有可能导致非常尴尬的结果,比标量整数更为严重,如果它们在没有先定义的情况下被引用。


有没有一些示例展示使用 intent(inout)intent(out) 会产生不同的输出? - user758077
1
@Jack,这个问题涉及一个_无效_程序。如果你想要一个使用intent(inout)而不是intent(out)的_有效_程序,那么你必须更加努力:对于一个intent(out)的虚参,在过程中对它的引用必须遵循该过程中的定义 - 这将覆盖可比较的intent(inout)虚参的定义。然而,是的,只需将intent(inout)更改为intent(out)或反之亦然,就可能使有效的程序产生不同的结果。评论无法展示这一点,所以如果您足够热心,请提一个新问题。 - francescalus
谢谢您的回复!我在搜索是否有类似的问题或解决方案。看起来没有。我很快会发布一个问题。 - user758077
已经发布了一个后续问题:https://dev59.com/ALfna4cB1Zd3GeqPq1dO - user758077

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接