And*_*ker 33 fortran fortran90
良好实践规定Fortran中的子例程参数应该都具有指定的意图(即intent(in),intent(out)或者如此问题intent(inout)所描述的):
subroutine bar (a, b)
real, intent(in) :: a
real, intent(inout) :: b
b = b + a
...
Run Code Online (Sandbox Code Playgroud)
但是,未指定intent是有效的Fortran:
subroutine bar (a, b)
real, intent(in) :: a
real :: b
b = b + a
...
Run Code Online (Sandbox Code Playgroud)
在编译时检查指定intent(inout)的参数和没有指定意图的参数之间是否存在任何真正的差异?如果我正在改进对较旧的,无意图的代码的意图,我还有什么可担心的吗?
M. *_* B. 22
根据Adams等人的Fortran 2003手册,一个intent(inout)参数和没有指定intent的参数之间存在一个区别.在intent(inout)情况下的实际参数(即在调用者中)必须始终是可定义的.如果未指定intent,则必须可以定义参数,如果子例程的执行尝试定义伪参数. 可定义表示设置值:dummy_arg = 2.0.显然,如果这样做,实际参数应该是一个变量.对于intent(inout),无论子例程是否执行此操作,实际参数都必须是可定义的.在没有指定意图的情况下,它取决于子例程的特定调用会发生什么 - 如果子例程没有定义变量,则可以; 如果确实如此,那么就会出现问题 - 例如写入一个常量的实际参数会导致问题.
这并不意味着编译器将诊断所有这些情况 - 标准要求编译器诊断的是另一个问题.在编译时检测意图未指定的案例要求的所有错误几乎是不可能的,因为违规取决于代码的运行时流程.编译器更容易诊断intent(inout)情况并警告您代码出现问题.
如果您的代码将PARAMETER作为您的子程序然后尝试写入的实际参数传递,那么您的问题会让我想知道(现在很多事情)是否会遇到行为上的差异.没有INTENT声明,编译器可能会放弃它,导致奇怪的行为.声明我希望有一个编译时错误.
你和我可能认为INOUT和没有INTENT声明之间没有区别,但是不要忘记那里有很多旧的Fortran程序,并且与旧语言版本的兼容性是新标准的一个重要特征.如果它是正确的(但是狡猾的)FORTRAN77,那么很多人都希望他们的代码能够使用Fortran 90+编译器保持正确(仍然是狡猾的).
快速阅读2003标准确实表明INOUT和无INTENT之间存在差异,但需要更接近读数.如果您进行测试,请告诉我们您的结论; 如果我以后有时间,我会亲自测试并告诉你.
小智 6
要理解意图输入/输出的作用,您需要知道 Fortran 在内部通过引用有效地传递变量。这并不总是与实际通过引用传递相同。
如果将二维数组的内部子部分传递给子例程,即:data(i1:i2, j1:j2),则 Fortran 会将该数据复制到内存的连续部分,并将新地址传递给例程。返回后,数据将被复制回其原始位置。
通过指定INTENT,编译器可以知道跳过其中一项复制操作。
它不仅可以作为修改您希望保持不变的数据的故障保护,而且还可以在处理大型数据集时加快您的代码速度。