2011-02-23 1 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 

아주 짧게 main은 x를 할당 한 다음 sub1 (x)를 호출합니다. 그런 다음 sub1이 sub2 (x)를 호출합니다. 이는 할당 된 배열을 다른 서브 루틴으로 전달하는 서브 루틴으로 전달됨을 의미합니다. 나는 main에서 만든 동일한 배열을 sub2에 가질 것으로 기대하지만, 그렇지 않습니다. 그것을 탐구하는 도구로 GDB를 사용하여,이 얻을 :

주에서, 단지 SUB1을 호출하기 전에, 배열 X는 완벽하게 정의

1) :

(GDB) PX
$ 1 = (5, 0 단지 SUB2를 호출하기 전에, 0, 0, 0, 0, 0, 0, 0, 0)

2) SUB1 내에서, 배는 잘 정의되어

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

3) SUB2 내부 그러나, X 예상치 못한 값과 심지어는 차원이 절대적으로 잘못된 것입니다 :

(GDB) PX =()
(GDB
$ 3) whatis는 X
유형 = REAL (4) (0 : -1)

따라서 x는 main에서 sub1로 성공적으로 전달되었지만 sub1에서 sub2로는 전달되지 않았습니다. 나는 인텔 포트란과 같은 결과를 가진 gfortran을 사용 해왔다.

나는 오랫동안 그걸로 어려움을 겪었습니다. 어떤 도움이라도 대단히 감사 할 것입니다.
G.Oliveira.

답변

10

가정용 임시 인수의 사용에는 명시적인 인터페이스가 필요합니다. 주 프로그램에서 두 서브 루틴에 대한 명시 적 인터페이스를 제공했지만 서브 루틴 자체로 전파되지는 않습니다. 서브 루틴은 하나의 소스 파일에 모든 코드를 넣었더라도 별도의 단위로 컴파일됩니다.
이것은 sub1이 sub2에 사용할 수있는 명시 적 인터페이스를 가지고 있지 않으므로 암시 적 인터페이스를 사용한다는 것을 의미합니다. 여기서 인수 x는 실제 스칼라로 간주됩니다.

이 모든 것은 두 개의 서브 루틴을 모듈에 넣고 그 모듈을 주 프로그램의 use에두면 간단히 피할 수 있습니다. 자동으로 명시 적 인터페이스를 사용할 수 있습니다. 이렇게하면 인터페이스를 직접 제공 할 필요가 없으며 오류가 발생하기 쉽습니다.

참고로 모든 코드에서 내재적 인 none을 사용하는 것이 좋습니다.

+3

다른 쪽 메모 : 질문에 fortran을 추가 할 수 있습니다. 더 많은 사람들이 단지'fortran90'을 따릅니다. – eriktous

+0

+1. @ user630900, 나쁘지 않아. 이것은 항상 발생하는 공통적이고 다소 미묘한 문제입니다 - 예 : http://www.cs.rpi.edu/~szymansk/OOF90/bugs.html#8 –

+1

@erikous : 정확하게 대답했습니다! 모듈의 모든 서브 루틴을 사용하면 모든 것이 완벽하게 작동합니다. 고마워. – user630900