未报告 Fortran 77 中参数错误的排名不匹配
Rank mismatch in argument error in Fortran 77 not being reported
我正在尝试将一段代码从 Fortran 77 移植到 Fortran 90,我有一个关于在 Fortran 77 中捕获等级不匹配的问题。
这是 Fortran 90 中的代码
program test
use my_module
real ml_time
call gettimes(cdfid,ml_time,ml_ntimes)
在调用子程序中,传递的变量是这样定义的
module my_module
use netcdf
subroutine gettimes(cdfid,times,ntimes)
real times(*)
call check(nf90_inq_dimid(cdfid,'time', timid))
call check(nf90_inquire_dimension(cdfid, timid, len = ntimes))
call check(nf90_inq_varid(cdfid,'time',timid))
call check(nf90_get_var(cdfid,timid,times(1:ntimes)))
end subroutine gettimes
在 Fortran 77(.f 文件)和 gfortran 5.4 中,为什么这不会产生编译错误?
当我将它移植到 Fortran 90 时,相同的代码产生了等级不匹配编译错误。
这是 Fortran 90 中的错误
add2p.f90:191:22:
call gettimes(cdfid,ml_time,ml_ntimes)
1
Error: Rank mismatch in argument ‘times’ at (1) (rank-1 and scalar)
在 Fortran 77 中,代码是这样组织的
program test
real ml_time
call gettimes(cdfid,ml_time,ml_ntimes)
在另一个文件中xyz.f
subroutine gettimes(cdfid,times,ntimes,ierr)
include "netcdf.inc"
integer ierr,i
real times(*)
integer didtim,ntimes
integer cdfid,idtime
do 10 i=1,ntimes
call ncvgt1(cdfid,idtime,i,times(i)) ! get times
10 continue
end
当然,我通过将它们设置为相同等级来消除错误,但我想知道为什么在 Fortran 77 中没有报告编译器错误。
您没有显示足够的代码来确定,但您可能在 Fortran 90 代码中使用了显式接口(例如,模块)。在那种情况下,编译器有义务检查这种不一致并且必须产生错误。使用隐式接口时情况并非如此(在 Fortran 77 中它们不是显式接口)。
仅当标量是数组元素时才允许将标量传递给假定大小的数组(参见序列关联)。
我确实在 gfortran 4.8 中收到警告,但如果调用在不同的源文件中,则可能不会发生:
subroutine s1(a)
integer :: a(*)
end
subroutine s2()
call s1(1)
end subroutine
> gfortran rank.f90 -c
rank.f90:7.12:
call s1(1)
1
Warning: Rank mismatch in argument 'a' at (1) (rank-1 and scalar)
请注意,编译器默认将每个源代码编译为 Fortran 2008 + 扩展。它不以任何方式区分 Fortran 90 和 77。
值得注意的是,.f 和 .f90 并不表示 Fortran 77 和 Fortran 90,它们表示固定格式和自由格式源。这两种源格式都是有效的 Fortran 90 - Fortran 2008。
我正在尝试将一段代码从 Fortran 77 移植到 Fortran 90,我有一个关于在 Fortran 77 中捕获等级不匹配的问题。
这是 Fortran 90 中的代码
program test
use my_module
real ml_time
call gettimes(cdfid,ml_time,ml_ntimes)
在调用子程序中,传递的变量是这样定义的
module my_module
use netcdf
subroutine gettimes(cdfid,times,ntimes)
real times(*)
call check(nf90_inq_dimid(cdfid,'time', timid))
call check(nf90_inquire_dimension(cdfid, timid, len = ntimes))
call check(nf90_inq_varid(cdfid,'time',timid))
call check(nf90_get_var(cdfid,timid,times(1:ntimes)))
end subroutine gettimes
在 Fortran 77(.f 文件)和 gfortran 5.4 中,为什么这不会产生编译错误?
当我将它移植到 Fortran 90 时,相同的代码产生了等级不匹配编译错误。
这是 Fortran 90 中的错误
add2p.f90:191:22:
call gettimes(cdfid,ml_time,ml_ntimes)
1
Error: Rank mismatch in argument ‘times’ at (1) (rank-1 and scalar)
在 Fortran 77 中,代码是这样组织的
program test
real ml_time
call gettimes(cdfid,ml_time,ml_ntimes)
在另一个文件中xyz.f
subroutine gettimes(cdfid,times,ntimes,ierr)
include "netcdf.inc"
integer ierr,i
real times(*)
integer didtim,ntimes
integer cdfid,idtime
do 10 i=1,ntimes
call ncvgt1(cdfid,idtime,i,times(i)) ! get times
10 continue
end
当然,我通过将它们设置为相同等级来消除错误,但我想知道为什么在 Fortran 77 中没有报告编译器错误。
您没有显示足够的代码来确定,但您可能在 Fortran 90 代码中使用了显式接口(例如,模块)。在那种情况下,编译器有义务检查这种不一致并且必须产生错误。使用隐式接口时情况并非如此(在 Fortran 77 中它们不是显式接口)。
仅当标量是数组元素时才允许将标量传递给假定大小的数组(参见序列关联)。
我确实在 gfortran 4.8 中收到警告,但如果调用在不同的源文件中,则可能不会发生:
subroutine s1(a)
integer :: a(*)
end
subroutine s2()
call s1(1)
end subroutine
> gfortran rank.f90 -c
rank.f90:7.12:
call s1(1)
1
Warning: Rank mismatch in argument 'a' at (1) (rank-1 and scalar)
请注意,编译器默认将每个源代码编译为 Fortran 2008 + 扩展。它不以任何方式区分 Fortran 90 和 77。
值得注意的是,.f 和 .f90 并不表示 Fortran 77 和 Fortran 90,它们表示固定格式和自由格式源。这两种源格式都是有效的 Fortran 90 - Fortran 2008。