Interface Fortran中的接口
在调试某些代码时,我偶然发现了接口的一个特殊问题,其中一个被调用的子例程有一个秩2的伪参数,但有一个秩1的实际参数。参数中产生的差异导致读取无效 为了重现,我创建了一个小程序(暂时忽略注释Interface Fortran中的接口,interface,fortran,Interface,Fortran,在调试某些代码时,我偶然发现了接口的一个特殊问题,其中一个被调用的子例程有一个秩2的伪参数,但有一个秩1的实际参数。参数中产生的差异导致读取无效 为了重现,我创建了一个小程序(暂时忽略注释!): 在模块中?或者我应该用延迟形状数组(即实型、可分配、维度(:,:)::field)替换字段的定义吗 编辑:为了更准确地回答我的问题,我不想解决这个特定的问题,但想知道如何从编译器获得更好的诊断输出 例如,给定的代码不会给出错误消息,原则上会产生分段错误(尽管代码没有注意到)。放置泛型接口至少会产生一个错
!
):
在模块中?或者我应该用延迟形状数组(即实型、可分配、维度(:,:)::field
)替换字段的定义吗
编辑:为了更准确地回答我的问题,我不想解决这个特定的问题,但想知道如何从编译器获得更好的诊断输出
例如,给定的代码不会给出错误消息,原则上会产生分段错误(尽管代码没有注意到)。放置泛型接口至少会产生一个错误,抱怨找不到与stest
匹配的定义,这也没有什么帮助,尤其是在没有源代码的情况下。只有延迟形状数组会产生可理解的错误消息(秩不匹配)
这就是为什么自动模块接口没有给出类似的警告/错误消息。编译器无法警告您,因为代码是合法的!您只是传递了错误的
n
和非平方的点数。对于显式形状阵列,您需要负责正确的尺寸标注。考虑
ALLOCATE(field(1000))
CALL stest(10, field, s)
尽管实际参数和伪参数的元素数量不同,但此代码仍能工作。可能会建议gfortran开发人员检查伪参数是否较大,但我不确定这有多困难
泛型接口使编译器检查TKR规则。不允许不同秩数组的序列关联,编译将失败。因此,它将禁用将不同秩的数组传递到显式形状和假定大小伪参数的所有合法用途,并限制您的可能性
解决办法是什么?在它们适合的情况下使用显式形状数组,在其他情况下使用假定形状数组(可能使用
continuous
属性)。通用接口可能也会有所帮助,但会更改语义并限制可能的使用。最简单的解决方案是在主程序中将字段声明为秩2数组。(即REAL,ALLOCATABLE,DIMENSION(:,:)::field
)并将其分配到子例程中使用的大小。那么实际参数和伪参数是一致的。您不想这样做有什么原因吗?您也可以传递字段(1)并获取“序列关联”。可以使用序列关联,但元素不匹配的数量也必须固定。秩-1 100元素可以匹配秩-2 10x10。感谢澄清。现在,我必须告诉我的同事,谁产生了这段代码,在未来做什么。。。我并没有真正考虑这样一个事实,即它可能是完全有效的代码,因为例如,通用接口确实会抱怨。
MODULE mtest ! <>
IMPLICIT NONE ! <>
CONTAINS ! <>
SUBROUTINE stest(n, field, erg)
INTEGER :: n
REAL, DIMENSION(n,n) :: field
REAL :: erg
erg = SUM(field)
END SUBROUTINE
END MODULE ! <>
INTERFACE stest
MODULE PROCEDURE stest
END INTERFACE
ALLOCATE(field(1000))
CALL stest(10, field, s)