2011-02-23 38 views
4

我有问题调用具有假定形状阵列连续子程序用Fortran 90.更具体地,我调用子例程的两个级别,传递一个假定形状阵列一个参数,但最终阵列会丢失。为了演示它,可以按照下面的代码。通过假定形状阵列在子程序的两个级别(Fortran 90中)

program main 

    INTERFACE 
    subroutine sub1(x) 
     real, dimension(:):: x 
     real C 
    end subroutine sub1 

    subroutine sub2(x) 
     real, dimension(:):: x 
     real C 
    end subroutine sub2 
    END INTERFACE 

    real, dimension(:), allocatable:: x 

    allocate(x(1:10)) ! First executable command in main 
    x(1) = 5. 
    call sub1(x) 
    write(*,*) 'result = ',x(1) 
    deallocate(x) 
    end program main 

    subroutine sub1(x) ! The first subroutine 
    real, dimension(:):: x 
    real C 
    call sub2(x) 
    end subroutine sub1 

    subroutine sub2(x) ! The second subroutine 
    real, dimension(:):: x 
    real C 
    C2=x(1) 
    end subroutine sub2 

很快,主分配x然后调用sub1(x)。然后sub1调用sub2(x)。这意味着一个分配的数组被传递给一个将其传递给另一个子例程的子例程。我期望在sub2中有与我在main中创建的相同的数组,但不是。用gdb,探讨它的工具,我得到这样的:

1)在主,只调用SUB1之前,阵列x被完全定义:

(GDB)PX
$ 1 =(5,0 ,0,0,0,0,0,0,0,0)

2)在SUB1,只是调用SUB2之前,X也良好定义:

(GDB)PX
$ 2 =( 5,0,0,0,0,0,0,0,0,0)

3)内部SUB2,然而,X会有意想不到的价值,甚至是尺寸绝对是错误的:

(GDB)PX
$ 3 =()
(GDB)头朝下X
类型= REAL(4) (0:-1)

因此,x已经成功地从main传递给了sub1,而不是从sub1传递到了sub2。我一直在使用英特尔Fortran和同样的结果。

我很久以来一直在努力。任何帮助将非常感激。
G.Oliveira。

回答

10

使用假定形状的虚拟参数需要一个明确的接口。 在你的主程序中,你已经为两个子程序提供了明确的接口,但是这些不会传播到子程序本身。子例程被编译为独立的单元,即使您已将所有代码放入一个源文件中。
这意味着sub1没有可用于sub2的显式接口,因此使用隐式接口,其中参数x被假定为实数标量。

所有这一切都可以简单地通过将两个子程序模块中,并use该模块在你的主程序,自动使明确的接口可用来避免。这样你就不必亲自提供接口,这很容易出错。

作为一个方面说明,我建议在您的所有代码中使用隐式无。

+3

另一方面说明:您可能需要为您的问题添加标签'fortran'。更多的人关注的不仅仅是“fortran90”。 – eriktous 2011-02-24 12:28:45

+0

+1。 @ user630900,别难过;这是一个常见的有点微妙的问题 - 例如,http://www.cs.rpi.edu/~szymansk/OOF90/bugs.html#8 – 2011-02-24 20:55:03

+1

@erikous:正确回答!通过模块中的所有子例程,一切都可以正常工作。非常感谢。 – user630900 2011-02-25 11:14:14