我有一些遗留的 Fortran 77 代码,我试图至少在不发出警告的情况下进行编译(不禁用警告)。有些子例程调用会传递一个标量,而子例程需要一个数组,因为标量被用作大小为 1 的数组,所以这不会导致任何问题。但是使用英特尔编译器,如果我启用接口警告,我会得到这个error:
error #8284: If the actual argument is scalar, the dummy argument shall be scalar unless the actual argument is of type character or is an element of an array that is not assumed shape, pointer, or polymorphic.
在某些情况下,我尝试通过使用数组和标量变体重载子例程来解决此问题,但是当传递的参数是“数组的元素”(被检测为标量)时,我会遇到问题。考虑以下示例(使用 gfortran 测试):
program a
integer n,dum(3)
interface readn
subroutine readn_s(n,m)
integer m,n
end subroutine
subroutine readn_a(n,m)
integer m,n(*)
end subroutine
end interface
call readn(n,1)
write(6,*) 'n=',n
call readn(dum,3)
write(6,*) 'dum=',dum
call readn(dum(2),2)
write(6,*) 'dum=',dum
end program
subroutine readn_s(n,m)
integer i,m,n
n=2
end subroutine
subroutine readn_a(n,m)
integer i,m,n(*)
do i=1,m
n(i)=1
end do
end subroutine
The readn(dum,3)
正确调用使用readn_a
,而第二个使用readn_s
。预期的行为是两者都应该使用readn_a
。事实上,如果我将这两个调用替换为readn_a
一切都如预期。
当实际参数是数组元素时,是否可以使其正常工作并使用重载例程的“数组”版本?我发现如果我调用子例程它会起作用readn(dum(2:),2)
,但恐怕会创建数组的临时副本......
原来的问题:
file.f90
program a
integer n,dum(3)
call readn_a(n,1)
write(6,*) 'n=',n
call readn_a(dum,3)
write(6,*) 'dum=',dum
dum=3
call readn_a(dum(2),2)
write(6,*) 'dum=',dum
end program
文件2.f90
subroutine readn_a(n,m)
integer i,m,n(*)
do i=1,m
n(i)=1
end do
end subroutine
编译用gfortran -Wall file.f90 file2.f90
or ifort file.f90 file2.f90
,一切都很好,输出是预期的:
n= 1
dum= 1 1 1
dum= 3 1 1
编译用ifort -warn all file.f90 file2.f90
我得到了error #8284
多于。所以这就是为什么我想要一个可以处理标量或数组的子例程版本......但会给出带有数组元素的数组版本。