Fortran意图(inout)与省略意图

时间:2010-05-21 08:26:40

标签: fortran fortran90

良好实践规定Fortran中的子例程参数应该具有指定的意图(即intent(in)intent(out)intent(inout),如this question所述):

subroutine bar (a, b)
    real, intent(in) :: a
    real, intent(inout) :: b
    b = b + a
    ...

但是,未指定intent是有效的Fortran:

subroutine bar (a, b)
    real, intent(in) :: a
    real :: b
    b = b + a
    ...

除了编译时检查指定为intent(inout)的参数和没有指定意图的参数之间是否存在任何实际差异?如果我正在改进对较旧的,无意图的代码的意图,我还有什么可担心的吗?

3 个答案:

答案 0 :(得分:21)

根据Adams等人的 Fortran 2003手册,一个intent(inout)参数和没有指定intent的参数之间存在一个区别。在intent(inout)情况下的实际参数(即在调用者中)必须始终是可定义的。如果未指定intent,则参数必须是可定义的如果子例程的执行尝试定义伪参数。 definable 表示设置值:dummy_arg = 2.0。显然,如果这样做,实际参数应该是一个变量。对于intent(inout),无论子例程是否执行此操作,实际参数都必须是可定义的。在没有指定意图的情况下,它取决于子例程的特定调用会发生什么 - 如果子例程没有定义变量,则可以;如果确实如此,那么就会出现问题 - 例如写入一个常量的实际参数会导致问题。

这并不意味着编译器将诊断所有这些情况 - 标准要求编译器诊断的是另一个问题。在编译时检测意图未指定的案例要求的所有错误几乎是不可能的,因为违规取决于代码的运行时流程。编译器更容易诊断intent(inout)情况并警告您代码出现问题。

答案 1 :(得分:6)

如果您的代码将PARAMETER作为您的子程序然后尝试写入的实际参数传递,您的问题会提醒我(如果您现在要做的很多)是否会遇到行为上的差异。没有INTENT声明,编译器可能会放弃它,导致奇怪的行为。声明我希望有一个编译时错误。

你和我可能认为INOUT和没有INTENT声明之间没有区别,但是不要忘记那里有很多旧的Fortran程序,并且与旧语言版本的兼容性是新标准的一个重要特征。如果它是正确的(但是狡猾的)FORTRAN77那么很多人都希望他们的代码能够使用Fortran 90+编译器保持正确(仍然是狡猾的)。

快速阅读2003标准确实表明INOUT和无INTENT之间存在差异,但需要更接近读数。如果您进行测试,请告诉我们您的结论;如果我以后有时间,我会亲自测试并让你知道。

答案 2 :(得分:3)

要了解intent in / out的作用,你需要知道在内部,Fortran 有效地通过引用传递变量。这并不总是与实际通过引用传递相同。

如果将2-D数组的内部子部分传递给子例程,即:data(i1:i2, j1:j2),则Fortran会将该数据复制到连续的内存部分,并将新地址传递给例程。返回后,数据将被复制回原始位置。

通过指定INTENT,编译器可以知道跳过其中一个复制操作。

它不仅可以作为修改您希望保持不变的数据的故障保护,还可以在处理大型数据集时加快代码。