为什么这个Fortran模块接口会根据使用的函数数量给出不同的结果?
我编写了一个模块,其中包含一个名为“push”的接口,该接口将值推送到可分配数组上。我希望它具有泛型行为,以便根据需要为给定类型向“push”接口添加新函数。问题是,随着给定接口的函数数量的增加,推送接口的奇怪行为也会增加 模块代码(push_array.f90): 测试代码(Test\u push\u array.f90): 生成输出以显示编译器标志:为什么这个Fortran模块接口会根据使用的函数数量给出不同的结果?,fortran,gfortran,generic-programming,allocatable-array,Fortran,Gfortran,Generic Programming,Allocatable Array,我编写了一个模块,其中包含一个名为“push”的接口,该接口将值推送到可分配数组上。我希望它具有泛型行为,以便根据需要为给定类型向“push”接口添加新函数。问题是,随着给定接口的函数数量的增加,推送接口的奇怪行为也会增加 模块代码(push_array.f90): 测试代码(Test\u push\u array.f90): 生成输出以显示编译器标志: $ make gfortran -g -O2 -c push_array.f90 gfortran -g -O2 -o main test_p
$ make
gfortran -g -O2 -c push_array.f90
gfortran -g -O2 -o main test_push_array.f90 push_array.o
我的编译器版本:
$ gfortran --version
GNU Fortran (GCC) 4.8.2
Copyright (C) 2013 Free Software Foundation, Inc.
我的系统:
$ uname -a
Darwin darthan 12.5.0 Darwin Kernel Version 12.5.0: Sun Sep 29 13:33:47 PDT 2013; root:xnu-2050.48.12~1/RELEASE_X86_64 x86_64
如果我按照给定的方式运行测试代码,它将进入无限循环,我的系统内存将完全耗尽。我试图通过设置断点来跟踪gdb中的测试用例,在第一个循环中我将I推到a上,但gdb无法进入模块函数
如果我只对第一个测试循环进行注释,其中我被推到了a上,那么结果如下:
$ ./main
1 100
1 2 3 100 101 102
1.0010000467300415 1.0019999742507935 1.0030000209808350 100.00099945068359 100.00199890136719 100.00299835205078
$ ./main
1 100
1 2 3 100 101 102
1.0010000467300415 1.0019999742507935 1.0030000209808350 100.00099945068359 100.00199890136719 100.00299835205078
这是意料之中的
如果我只注释第二个循环,将j推到b上,结果如下:
$ ./main
1 100
1 2 3 100 101 102
1.0010000467300415 1.0019999742507935 1.0030000209808350 100.00099945068359 100.00199890136719 100.00299835205078
$ ./main
1 100
1 2 3 100 101 102
1.0010000467300415 1.0019999742507935 1.0030000209808350 100.00099945068359 100.00199890136719 100.00299835205078
再一次,如预期的那样
当我把xp推到c上的第三个循环注释掉时,事情开始变得奇怪:
$ ./main
1 0
1 0
1.0010000467300415 1.0019999742507935 1.0030000209808350 100.00099945068359 100.00199890136719 100.00299835205078
当我注释掉将xp8推到d上的第四个循环时,模式继续:
$ ./main
1 0
1 0
1 2 3 100 101 102
我的问题是:
function push_scalar_int_onto_rank1_int (array,val) result (new_array)
integer,intent(in),allocatable :: array(:)
integer,intent(in) :: val
integer,allocatable :: new_array(:)
integer :: length
if (allocated(array)) then
length = size(array) + 1
else
length = 1
end if
allocate(new_array(length)) ! changed
if (allocated(array)) new_array(:) = array(:)
new_array(length) = val
return
end function push_scalar_int_onto_rank1_int
function push_scalar_int2_onto_rank1_int2 (array,val) result (new_array)
integer(2),intent(in),allocatable :: array(:)
integer(2),intent(in) :: val
integer(2),allocatable :: new_array(:)
integer :: length
if (allocated(array)) then
length = size(array) + 1
else
length = 1
end if
allocate(new_array(length)) ! changed
if (allocated(array)) new_array(:) = array(:)
new_array(length) = val
return
end function push_scalar_int2_onto_rank1_int2
您可以在一些函数体中的allocate语句引用
数组
参数的大小。如果未分配数组
参数,则该引用无效
在前面的过程中,您测试了分配状态,并设置了一个名为length
的变量-也许您想使用它
(为了清楚起见,请查看
push_scalar_int_to_rank1_int
函数中的allocate语句。)IanH解释了这个问题。编译器可以帮助您找到它。根据编译选项的不同,我从gfortran 4.8中得到了不同的响应。使用-O2-fimplicit none-Wall-Wline truncation-Wcharacter truncation-Wsurprising-Waliasing-Wimplicit interface-Wunused参数-fcheck=all-std=f2008-pedantic-fbacktrace进行编译,然后给出运行时错误:
At line 25 of file push.f90
Fortran runtime error: Index '1' of dimension 1 of array 'new_array' above upper bound of -265221874
第25行是中return
之前的一行,如果我打印返回的数组是否为“a”,则将\u scalar\u int\u推到\u rank1\u int
在gfortran主程序的循环中分配。它返回true,ifort返回false。问题是a
的初始分配状态-当函数在循环的第一次迭代中返回时,事情已经变糟了。奇怪的是,我在运行时使用这些标志没有收到任何错误消息,仍然挂起。如果它把它扔了就好了!