运行我的代码(使用gfortran编译)时,我得到了fortran运行时警告“创建了一个数组临时”,我想知道是否有更好的方法来解决此警告。
我的原始代码是这样的:
allocate(flx_est(lsign,3))
allocate(flx_err(lsign,3))
do i=1,lsign
call combflx_calc(flx_est(i,:),flx_err(i,:))
enddo
在子程序中,我定义了这样的变量:
subroutine combflx_calc(flx_est,flx_err)
use,intrinsic :: ISO_Fortran_env, only: real64
implicit none
real(real64),intent(inout) :: flx_est(3),flx_err(3)
flux_est
和flx_err
向量可能会在子程序内部发生变化,具体取决于几个条件,我需要相应地更新它们的值。
Fortran似乎不喜欢这种结构。我可以解决它定义临时变量:
tmp_flx_est=flx_est(i,:)
tmp_flx_err=flx_err(i,:)
call combflx_calc(tmp_flx_est,tmp_flx_err)
flx_est(i,:)=tmp_flx_est
flx_err(i,:)=tmp_flx_err
但在我看来,修复它是一种愚蠢的方式。
正如您所看到的,我不是Fortran的专家,所以任何帮助都非常受欢迎。
答案 0 :(得分:9)
一种方法是传递假定的形状数组
real(real64),intent(inout) :: flx_est(:),flx_err(:)
另一种是交换数组的尺寸,以便您可以传递2D数组的连续部分。
call combflx_calc(flx_est(:,i),flx_err(:,i))
问题是你的过程(var(n)
)的显式大小伪参数需要连续的数组。假设的形状数组可以有一些步幅。
答案 1 :(得分:7)
正在创建数组临时,因为您正在将一个跨步数组传递给子例程。 Fortran数组是列主要的,因此最左边的索引在数组中变化最快,或者更好地说,最左边的索引在内存中是连续的,而右边的每个变量都跨越左边的那些。
致电时
call combflx_calc(flx_est(i,:),flx_err(i,:))
这些切片是由lsign长度划分的3向量的数组。子例程期望内存中的单个维度的变量是连续的,而传递给它的变量则不是。因此,必须对子例程进行临时操作,然后将其复制回数组切片。
你的"修复"不会改变这一点,它只是不再警告临时因为你使用的是显式创建的变量,而不是运行时为你做的。
弗拉基米尔的回答为你提供了避免临时的选择,所以我不会在这里复制它们。