2016-09-15 6 views
1

가능한 한 적은 수정으로 예전 코드를 가진 새로운 Fortran 90 모듈을 어떻게 인터페이스합니까? 아이디어는 서브 루틴에서 새 코드에 "모듈"을 사용하고 가능한 한 거의 수정하지 않고 (즉, 공통 블록을 그대로 둡니다) 이전 코드를 그대로 두는 것입니다.공통 블록과 모듈간에 데이터를 공유하는 방법은 무엇입니까?

간단한 프로그램을 고려 :

내가 달성하고자하는 것을 보여주기 위해, 여기에 간단한 프로그램입니다

module Bmod 
    real*8 x 
    end module Bmod 

    program main 
    use Bmod 
    common /a/ x ! old code      
    do i=1, 5 
     x=3.14159 ! do something with x in fortran77 
     call B() ! new f90 code 
    enddo 
    end program main 

    ! new features added here 
    subroutine new_code() 
    use Bmod 
    write(*,*) 'x in B=', x 
    end subroutine new_code 

을하지만 컴파일하는 동안 오류가 발생합니다 :

error #6401: The attributes of this name conflict with those made accessible by a USE statement. [X] 
    common /a/ x 

간단한에게 해결책은 어디서나 일반적인 것을 타야한다는 것입니다. 하지만 그것은 오래된 코드를 수정하므로 내 경우에는 허용되지 않습니다. 게다가 오래된 코드는 구식으로 쓰여진 몇 개의 공통 블록에 퍼져있는 수천 개의 변수로 구성됩니다.

+1

@khakishoiab 편집시주의하십시오. 수정 사항이 승인되어서는 안됩니다. Fortran 90은 FORTRAN90이 아닌이 방법으로 작성됩니다. 문장에 두 번째 동사를 추가했습니다. 동사 * 인터페이스 *는 괜찮 았습니다. 거기에 * 사용 *을 추가 할 수는 없으며 * 인터페이스 * 만 삭제하고 대신 * 사용 *을 추가 할 수 있습니다. 또한 하단 (단점)에서 두 문장 사이의 누락 된 부분을 놓쳤습니다. –

+1

Nice review @VladimirF – khakishoiab

+0

'real * 8 '은 Fortran이 유효하지 않으며 ISO Fortran/FORTRAN 표준에 포함되지 않았습니다. – jlokimlin

답변

2

모듈 내에 공통 블록 정의를 넣을 수 있습니다. 이 경우 두 가지를 결합 할 수 있지만 액세스 방법에주의해야합니다.

모듈을 통해 이미 액세스 한 모든 유닛에서 공통 블록을 정의 할 수 없습니다. 귀하의 오류 메시지에 대해서는

module Bmod 
    real*8 x 
    common /a/ x ! old code      
    end module Bmod 

    program main 
    real*8 x 
    common /a/ x ! old code      
    do i=1, 5 
     x=3.14159 ! do something with x in fortran77 
     call new_code() ! new f90 code 
    enddo 
    end program main 

    ! new features added here 
    subroutine new_code() 
    use Bmod 
    write(*,*) 'x in B=', x 
    end subroutine new_code 

:

당신이 보여 코드가 잘못

당신은 당신이 말하는

use Bmod !x is in Bmod 

다음 모듈에서 첫 수입 기호 x 그것은 지명 된 공통 블록에있다

common /a/ x 

둘 중 하나를 가질 수도 있고, 둘 다 가질 수도 없습니다. 모듈 변수 또는 공통 블록의 변수를가집니다.

모든 공통 블록을 한꺼번에 삭제할 필요는 없습니다. 한 번에 하나의 전체 공통 블록조차 없습니다. 하지만 일단 변수를 모듈로 옮기면 동시에 같은 변수를 가질 수 없습니다. 한 번에 하나의 변수를 사용하여 공통 블록에서 변수를 삭제하고 모듈에 넣으려는 경우 모듈에 배치 할 수 있습니다.

+0

나는 당신의 테스트 프로그램을 돌렸다. 이 두 가지 대답은별로 다르지 않지만이 것을 받아들입니다. – wander95

2

변수가 선언되는 방식을 변경하려면 모든 곳에서 일관되게이를 수행해야합니다. (! 좋은 선택) 이제 별도의 모듈에 x의 선언을 이동하려면

program common 
    implicit none 
    real*8 x 
    common /a/ x 
    x = 3.0 
    call mysub() 
    print *, x 
end program common 

subroutine mysub() 
    implicit none 
    real*8 x 
    common /a/ x 
    x = 4.0 
end subroutine mysub 

, 당신은 일관되게해야 할 :

난 당신이 뭔가를했다 가정합니다. 즉, 모듈에서 x을 선언 할 수 없으면 프로그램에서 x을 공통 블록의 일부로 만듭니다.

가장 좋은 방법은 완전히 일반적인 블록을 제거하는 것입니다 :

module mymod 
    implicit none 
    real*8 x 
    common /a/ x 
end module mymod 

program common 
    use mymod 
    implicit none 
    x = 3.0 
    call mysub() 
    print *, x 
end program common 

subroutine mysub() 
    implicit none 
    real*8 x 
    common /a/ x 
    x = 4.0 
end subroutine mysub 
:
module mymod 
    implicit none 
    real*8 x 
end module mymod 

program common 
    use mymod 
    implicit none 
    x = 3.0 
    call mysub() 
    print *, x 
end program common 

subroutine mysub() 
    use mymod 
    implicit none 
    x = 4.0 
end subroutine mysub 

그러나 정치적인 이유로 당신이 COMMON 블록을 유지해야하는 경우, 당신은 모듈로 이동해야

는 (난 그냥이 글을 쓰는 더러운 기분이 ...) 물론

, 모듈에서 두 x와,887 경우

use mymod, only: y => x 

이 모듈의 x 사용할 수 y로 만들 것, 그대로 공통 x을 유지하면서 :블록은 항상 로컬로 자신의 이름을 변경할 수 있습니다, 동일하지 않습니다.

관련 문제