Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/fortran/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
为什么这个Fortran模块接口会根据使用的函数数量给出不同的结果?_Fortran_Gfortran_Generic Programming_Allocatable Array - Fatal编程技术网

为什么这个Fortran模块接口会根据使用的函数数量给出不同的结果?

为什么这个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

我编写了一个模块,其中包含一个名为“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_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
我的问题是:

  • 当我试图在同一个程序中使用push接口中定义的所有四个函数时,为什么主测试程序会进入无限循环

  • 在我注释掉第三个和第四个循环的情况下,为什么a(100)和b(100)的结果都等于0

  • 任何反馈都将不胜感激…谢谢

    编辑:

    下面给出了需要更改的两个功能

      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
    的初始分配状态-当函数在循环的第一次迭代中返回时,事情已经变糟了。奇怪的是,我在运行时使用这些标志没有收到任何错误消息,仍然挂起。如果它把它扔了就好了!