子程序中的 Fortran 数组不匹配但没有错误?
Fortran array mismatch in subroutine but no error?
我有一个似乎可以正常工作的程序,
但我不明白它怎么可能,
因为似乎有一个明显的错误。
主程序(使用'implicit')调用一个子程序:
implicit integer(i-n)
implicit double precision(a-h,o-y)
implicit complex*16(z)
call do_coulomb(zvecs0,zdualvecs0,n_f,n_f,1,
$ nsubfilling,zcorrmatrix,0,aldet01abs,
$ zcoulomb,epsilon)
声明数组,'zvecs0','zdualvecs0','zcorrmatrix',
但是任何地方都没有 'nsubfilling' 的声明。
(这可能是旧版本的错误或遗留问题。)
因为找不到
主程序中数组 'nsubfilling' 的任何声明
('grep -i nsubfilling *'),
我想 'nsubfilling' 将被视为整数变量。
这是问题的子程序:
subroutine do_coulomb(zvecs,zdualvecs,n_A,n_Ap,n_C,
$ nsubfilling,zcorrmatrix,n1_p0,aldet01abs,
$ zcoulomb,eps)
implicit integer(i-n)
implicit double precision(a-h,o-y)
implicit complex*16(z)
include "input.inc"
dimension zvecs(0:L-1,0:L-1,0:L-1,0:Lt,0:1,0:1,0:n_f-1)
dimension zdualvecs(0:L-1,0:L-1,0:L-1,0:Lt,0:1,0:1,0:n_f-1)
dimension nsubfilling(0:n_Ap-1,0:n_C-1)
dimension zcorrmatrix(0:n_Ap-1,0:n_Ap-1)
('L' 'Lt' 在 "input.inc" 文件中定义。)
因为'nsubfilling'在子程序中定义为数组,
我以为主程序和子程序不匹配会导致错误。
但是,该程序似乎 运行 即使不匹配也可以。
我试图打印出一些变量。('n_f'=4,'n_c'=1 in this 运行)
这是输出:
Before 1st call in main:
nsubfilling= 1
zcorrmatrix(0,0)= (20.510951695209510,0.13579118691198364)
zcorrmatrix(0,1)= (-1.0490102491588316,0.59453967445518319)
zcorrmatrix(1,0)= (-1.3791781667351797,-0.26247624491732802)
zcorrmatrix(n_f-1,n_f-1)= (20.510951695209513,-0.13579118691198364)
Inside do_coulomb subroutine:
nsubfilling= 1 0 1 1
zcorrmatrix(0,0)= (20.510951695209510,0.13579118691198364)
zcorrmatrix(0,1)= (-1.0490102491588316,0.59453967445518319)
zcorrmatrix(1,0)= (-1.3791781667351797,-0.26247624491732802)
zcorrmatrix(n_f-1,n_f-1)= (20.510951695209513,-0.13579118691198364)
n1p0= 0
After 1st call in main:
nsubfilling= 1
zcorrmatrix(0,0)= (20.510951695209510,0.13579118691198364)
zcorrmatrix(0,1)= (-1.0490102491588316,0.59453967445518319)
zcorrmatrix(1,0)= (-1.3791781667351797,-0.26247624491732802)
zcorrmatrix(n_f-1,n_f-1)= (20.510951695209513,-0.13579118691198364)
输出显示 'nsubfilling' 在主程序中被视为整数,
但在子程序中被视为一个数组,并且
子例程正确识别 'zcorrmatrix'
即使不匹配。
可是,这怎么可能呢?我觉得应该是有错误。
你能告诉我它是如何工作的吗?
谢谢。
主程序没有子程序的显式接口do_coulomb
。这意味着主程序无法在编译时检查主程序中实际参数的等级是否与子程序中伪参数的等级相匹配。
可以通过多种方式提供显式接口:
将子例程do_coulomb
作为主程序的内部子程序(子例程在主子程序之后,CONTAINS
语句之后和END
语句之前main program),这就是所谓的主机关联;
通过主程序中的接口块(提供子程序名称、伪参数列表、它们的类型和属性);或
通过在模块内部包含子程序(foo
)并在隐式声明之前添加一个使用语句(use module foo
),这称为使用关联。
为什么你的程序没有崩溃?好吧,因为子例程 do_coulomb
认为它可以访问对应于子例程内部指定大小的 nsubfilling
的内存块,并且在操作它时恰好没有做任何其他非法的事情 - 的块内存恰好被同一个应用程序使用。如果 nsubfilling
的声明大小非常非常大,and/or 您声明的数组较少,访问 nsubfilling
可能会导致分段错误。
请注意,即使您有显式接口,等级和维度也可能不匹配 - 这可能是合法的,只要子例程中的虚拟参数的总大小不大于总大小主程序中实际参数的大小。
我有一个似乎可以正常工作的程序, 但我不明白它怎么可能, 因为似乎有一个明显的错误。
主程序(使用'implicit')调用一个子程序:
implicit integer(i-n)
implicit double precision(a-h,o-y)
implicit complex*16(z)
call do_coulomb(zvecs0,zdualvecs0,n_f,n_f,1,
$ nsubfilling,zcorrmatrix,0,aldet01abs,
$ zcoulomb,epsilon)
声明数组,'zvecs0','zdualvecs0','zcorrmatrix',
但是任何地方都没有 'nsubfilling' 的声明。
(这可能是旧版本的错误或遗留问题。)
因为找不到
主程序中数组 'nsubfilling' 的任何声明
('grep -i nsubfilling *'),
我想 'nsubfilling' 将被视为整数变量。
这是问题的子程序:
subroutine do_coulomb(zvecs,zdualvecs,n_A,n_Ap,n_C,
$ nsubfilling,zcorrmatrix,n1_p0,aldet01abs,
$ zcoulomb,eps)
implicit integer(i-n)
implicit double precision(a-h,o-y)
implicit complex*16(z)
include "input.inc"
dimension zvecs(0:L-1,0:L-1,0:L-1,0:Lt,0:1,0:1,0:n_f-1)
dimension zdualvecs(0:L-1,0:L-1,0:L-1,0:Lt,0:1,0:1,0:n_f-1)
dimension nsubfilling(0:n_Ap-1,0:n_C-1)
dimension zcorrmatrix(0:n_Ap-1,0:n_Ap-1)
('L' 'Lt' 在 "input.inc" 文件中定义。)
因为'nsubfilling'在子程序中定义为数组,
我以为主程序和子程序不匹配会导致错误。
但是,该程序似乎 运行 即使不匹配也可以。
我试图打印出一些变量。('n_f'=4,'n_c'=1 in this 运行) 这是输出:
Before 1st call in main:
nsubfilling= 1
zcorrmatrix(0,0)= (20.510951695209510,0.13579118691198364)
zcorrmatrix(0,1)= (-1.0490102491588316,0.59453967445518319)
zcorrmatrix(1,0)= (-1.3791781667351797,-0.26247624491732802)
zcorrmatrix(n_f-1,n_f-1)= (20.510951695209513,-0.13579118691198364)
Inside do_coulomb subroutine:
nsubfilling= 1 0 1 1
zcorrmatrix(0,0)= (20.510951695209510,0.13579118691198364)
zcorrmatrix(0,1)= (-1.0490102491588316,0.59453967445518319)
zcorrmatrix(1,0)= (-1.3791781667351797,-0.26247624491732802)
zcorrmatrix(n_f-1,n_f-1)= (20.510951695209513,-0.13579118691198364)
n1p0= 0
After 1st call in main:
nsubfilling= 1
zcorrmatrix(0,0)= (20.510951695209510,0.13579118691198364)
zcorrmatrix(0,1)= (-1.0490102491588316,0.59453967445518319)
zcorrmatrix(1,0)= (-1.3791781667351797,-0.26247624491732802)
zcorrmatrix(n_f-1,n_f-1)= (20.510951695209513,-0.13579118691198364)
输出显示 'nsubfilling' 在主程序中被视为整数, 但在子程序中被视为一个数组,并且 子例程正确识别 'zcorrmatrix' 即使不匹配。
可是,这怎么可能呢?我觉得应该是有错误。
你能告诉我它是如何工作的吗?
谢谢。
主程序没有子程序的显式接口do_coulomb
。这意味着主程序无法在编译时检查主程序中实际参数的等级是否与子程序中伪参数的等级相匹配。
可以通过多种方式提供显式接口:
将子例程
do_coulomb
作为主程序的内部子程序(子例程在主子程序之后,CONTAINS
语句之后和END
语句之前main program),这就是所谓的主机关联;通过主程序中的接口块(提供子程序名称、伪参数列表、它们的类型和属性);或
通过在模块内部包含子程序(
foo
)并在隐式声明之前添加一个使用语句(use module foo
),这称为使用关联。
为什么你的程序没有崩溃?好吧,因为子例程 do_coulomb
认为它可以访问对应于子例程内部指定大小的 nsubfilling
的内存块,并且在操作它时恰好没有做任何其他非法的事情 - 的块内存恰好被同一个应用程序使用。如果 nsubfilling
的声明大小非常非常大,and/or 您声明的数组较少,访问 nsubfilling
可能会导致分段错误。
请注意,即使您有显式接口,等级和维度也可能不匹配 - 这可能是合法的,只要子例程中的虚拟参数的总大小不大于总大小主程序中实际参数的大小。