具有子例程输入数组长度的Fortran等价语句
我正在更新一些旧的Fortran代码,但我无法在某个地方摆脱一个等价语句(长话短说:它的混合使用非常复杂,需要花费太多的工作才能转换所有内容) 我需要等效数组的长度取决于某些输入,如以下代码:具有子例程输入数组长度的Fortran等价语句,fortran,gfortran,equivalence,Fortran,Gfortran,Equivalence,我正在更新一些旧的Fortran代码,但我无法在某个地方摆脱一个等价语句(长话短说:它的混合使用非常复杂,需要花费太多的工作才能转换所有内容) 我需要等效数组的长度取决于某些输入,如以下代码: program test_equivalence implicit none
program test_equivalence
implicit none
type :: t1
integer :: len = 10
end type t1
type(t1) :: o1
call eqv_int(o1%len)
call eqv(o1)
return
contains
subroutine eqv_int(len)
integer, intent(in) :: len
integer :: iwork(len*2)
real(8) :: rwork(len)
equivalence(iwork,rwork)
print *, 'LEN = ',len
print *, 'SIZE(IWORK) = ',size(iwork)
print *, 'SIZE(RWORK) = ',size(rwork)
end subroutine eqv_int
subroutine eqv(o1)
type(t1), intent(in) :: o1
integer :: iwork(o1%len*2)
real(8) :: rwork(o1%len)
equivalence(iwork,rwork)
print *, 'LEN = ',o1%len
print *, 'SIZE(IWORK) = ',size(iwork)
print *, 'SIZE(RWORK) = ',size(rwork)
end subroutine eqv
end program test_equivalence
此程序将使用gfortran 9.2.0创建0长度数组。这是输出:
LEN = 10
SIZE(IWORK) = 0
SIZE(RWORK) = 0
LEN = 10
SIZE(IWORK) = 0
SIZE(RWORK) = 0
当使用gfortran 5.3.0编译时,相同代码将返回(1)处具有非常量边界的数组“rwork”
。那么可能是编译器的错误吗?源代码确实不是有效的Fortran程序。具体而言,它违反了Fortran 2018的编号约束C8106:
等价对象不应是具有基本对象的指示符,即。。自动数据对象
作为一个编号约束,编译器必须能够检测到这种冲突。如果没有这样的功能,这是编译器的一个缺陷(一个bug)。“有能力”并不意味着默认情况下会这样做,因此请仔细查看是否存在导致此检测的选项。熟悉GCC内部的人可以在这里提供更多细节
由于源不是有效的FORTRAN程序,如果跳过了违规检测,编译器被允许考虑大小为0的数组。< /P>编辑:同一代码将返回<代码>数组“ReWork”在(1)具有非恒定边界时,当用Gfortran 5.3.0编译时,不能是等效对象< /代码>。自gfortran 6.2.0以来,警告消失,但阵列的大小始终为0。那么可能是编译器错误?请回答您的问题,不要在评论中留下重要信息。@VladimirF,明白了,thanks@FedericoPerini请注意,主程序中的RETURN不是标准Fortran,应该删除-这不是C!另外,请阅读并理解为什么real(8)不是很好的练习题,所以我需要找到另一种方法来完成我所需要的。我有一个例程,其接口如下:
子例程sub(iwork,rwork)
其中integer::iwork(*)
和real(8)::rwork(*)
。由于这些数组是等价的,它们的用法在sub
中是整数/实数混合的,因此在代码中的其他地方只有一个唯一的实数工作区,sub称为调用sub(rwork,rwork)
。除了等价数组之外,我唯一的其他选择是执行类似于callsub(rwork,transfer(rwork,[0]))
的操作,但它不会通过引用传递传输的内容…顺便说一句-问题是编译器不会在同一模块内编译callsub(rwork,rwork)
,因为这是强制的类型检查。一个使用实/整数工作区等价性的40年前的程序可能只是为了节省内存:现在你可能可以只使用单独的变量。嗯,在gfortran中寻找一个选项,该选项可以检测到这一点,但找不到-我希望-std=至少可以检测到它。我想是时候发布错误报告了@如果你能添加到你的报告中,它看起来像是5.5版和6.5版之间的回归问题,在我的笔记本电脑上,它无法用前者编译,但用几周前下载的6.5、7.4和8.3版(以及10.0版(实验版))编译错误