如果将分配的数组传递给尺寸不匹配的子例程,如何使Fortran发出警告? [英] How to get Fortran to warn me if I pass an allocated array to a subroutine with mismatching dimensions?

查看:114
本文介绍了如果将分配的数组传递给尺寸不匹配的子例程,如何使Fortran发出警告?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我只是花了太多时间来解决程序中的错误.我调用一个子例程(让我们调用mysub),该子例程定义为:

I just spent too much time resolving a bug in my program. I call a subroutine (let's call is mysub) defined as:

subroutine mysub(hourval,dayval,some,more,args)
use globals
implicit none

real:: hourval(24,ncol,nrow)
real:: dayval(ncol,nrow)

...
end

其中,hourvaldayval是包含子例程中计算结果的数组,而nrowncol是整数.

where hourval and dayval are the arrays that contain the output of the calculations in the subroutine, and nrow and ncol are integers.

对子例程的调用看起来像

The call to the subroutine looks like

call mysub(daygrid,hourgrid,some,more,args)

其中,daygridhourgrid是先前allocate d的数组. hourgrid具有3个维度(24,ncol,nrow),而daygrid具有2个维度(ncol,nrow).到目前为止,提到的所有变量(hourgriddaygridnrowncol)都在模块globals中声明.

where daygrid and hourgrid are arrays that were previously allocated. hourgrid has 3 dimensions (24,ncol,nrow), while daygrid has 2 dimensions (ncol,nrow). All variables mentioned until now (hourgrid, daygrid, nrow, ncol) are declared in the module globals.

我一直得到奇怪的结果,最后注意到我在子例程调用中切换了hourgriddaygrid的顺序,并更改了此设置,从而解决了我的问题(程序中的实际变量名称不那么显式,这使得错误更难发现).但是,该程序可以正常编译,并且我不会在日志文件中得到任何相关的错误消息.

I kept getting strange results and finally noticed that I switched the order of hourgrid and daygrid in my subroutine call, and changing this solved my problem (the actual variables in my program have less explicit names, which made the mistake a bit harder to spot). However, the program would compile normally, and I would not get any relevant error messages in the logfile.

因此,我想知道是否有一种方法可以在编译时或运行时获取一条指向该错误的消息.我在Linux上使用带有以下编译器标志的Intel Fortran 11.1:

I'm wondering, therefore, if there is a way to get a message, either at compile-time or at run-time, pointing to that error. I'm using Intel Fortran 11.1 on Linux with the following compiler flags:

-O3 -C -pg -traceback -g

我实际上是指望-C标志(等同于-check all)来检测这种错误,因为它暗示了选项-check bounds.我还能做些什么吗?

I was actually counting on the -C flag (equivalent to -check all) to detect this kind of bugs, as it implies the option -check bounds. Is there anything else I can do?

推荐答案

使用假设形状"的建议确实很好(因此在其中+1),因为这会检测形状不匹配.但是,如果阵列的形状相同,则可能会再次遇到麻烦.原因是,如果参数匹配接口中的内容,编译器将无法知道您打算做什么.

The suggestion to use assume-shape is really good (so a +1 there), as that will detect shape mismatches. However, if your arrays have the same shape then you can run again into trouble. The reason is that there is no way the compiler can know what you intended to do if the arguments match what is in the interface.

因此,避免此问题的更好解决方案可能是使用命名参数(除了使用带有显式接口的假定形状).在下面的示例中,sunmoon是要处理的相似数组.当您切换它们时,子例程调用仍然有效,但是会互换使用数组.使用命名实参时,无论您按什么顺序输入,子程序都会将其连接到正确的伪实参.

So, a better solution to avoid the problem might be to use named arguments (in addition to using assumed shape with explicit interface that is). In the example below, sun and moon are similar arrays that are to be processed. When you switch them around, the subroutine call still works but interchanges the use of the arrays. When using named arguments, no matter what order you put them in, the subroutine will connect it to the correct dummy argument.

program named_arguments
integer, parameter :: n = 2
integer, allocatable :: sun(:,:), moon(:,:)

allocate(sun(n,n))
allocate(moon(n,n))

call mysub(sun,moon)

write(*,*) sun
write(*,*) moon

call mysub(moon,sun)

write(*,*) sun
write(*,*) moon

call mysub(night=moon,day=sun)

write(*,*) sun
write(*,*) moon

contains

subroutine mysub(day,night)
integer :: day(:,:), night(:,:)

day = 1
night = 2
end subroutine

end program

由于您可能给虚拟参数赋予了有意义的名称以反映它们的用法,因此通过名称将它们连接到调用中的实际参数是避免这种问题的一种好习惯.

As you probably give meaningful names to the dummy arguments that reflect their usage, connecting them by name to the actual arguments in the call is a good practice to avoid this kind of problem.

在您的情况下:

call mysub(dayval=daygrid,hourval=hourgrid,...)

将做正确的事情,因为使用命名参数不依赖于虚拟参数的顺序.

would do the correct thing as using named arguments doesn't rely on the order of the dummy arguments.

这篇关于如果将分配的数组传递给尺寸不匹配的子例程,如何使Fortran发出警告?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆