2011-10-04 4 views
1

내가 Linux 용 인텔 포트란 컴파일러 (버전 12.0.3) 내 프로그램을 컴파일하기 위해 노력하고있어 나는이 오류를 받고 있어요는 :포트란 컴파일러 오류

buggy.f90(206): error #6219: A specification expression object must be a dummy 
argument, a COMMON block object, or an object accessible through host or use 
association [SPECTRUM] 
    type(spect)      :: spectrum 
----------------------------------------^ 

이 모듈에 있습니다. type(spect)은 문제가되는 모듈의 시작 부분에있는 I use의 다른 모듈에서 가져온 것입니다. 여기에 몇 가지 코드가 있습니다. 자세한 내용은 아래에서 확인할 수 있습니다.

module non_buggy 

    implicit none 

    type axis 
     character(len=6) :: nucleus 
     integer   :: num_data_points 
     real    :: spectral_width 
    end type axis 

    type spect 
     integer     :: num_dim 
     type(axis), allocatable :: axes(:) 
     real, allocatable  :: intensity(:) 
     character(len=10)  :: type = '' 
    end type spect 

    type(spect), target :: spectrum ! might this be a cause of error? 

    contains 
    ! ... 
end module non_buggy 


module buggy 

    use non_buggy 

    implicit none 

    contains 

    subroutine no_problem_here() 

     type(spect) :: spectrum ! compiles beautifully 
     ! ... 
    end subroutine no_problem_here 

    subroutine problem() 
     type(spect) :: spectrum ! does not compile, but no error if I change the variable name 
     ! ... 
    end subroutine problem 
end module buggy 

나는 오류가 무엇을 의미하는지에 대해 읽고,하지만 난 내 코드에서 뭘하는지에 적용되지 않는 인상을 - 아니 배열 범위는 그 라인에 지정되지 않습니다. spectrum의 두 번째 항목의 이름을 다른 것으로 변경하면 문제가 모듈 변수 spectrum (모듈 non_buggy)에서 발생했는지 궁금합니다 (줄을 주석 처리하더라도 오류가 계속 발생 함). 모듈 변수가 선언 된). 포트란 전문가가 그 문제를 분명히 할 수 있다면 나는 가장 감사 할 것입니다.

미리 감사드립니다.

+1

오류는 다른 곳에서 발생합니다. 나는 심지어 모듈을 컴파일하려고 시도했다. 그러나 나는 문제의 근원이 다른 곳에 있다고 확신한다. 공유 한 코드의 평화에 아무런 문제가 없기 때문입니다. 가능한 경우 더 많은 코드를 입력하십시오. – Wildcat

+0

@kemiisto 당신은 절대적으로 옳았습니다! 나는 문제를 발견했다. 그것은 컴파일러가 지적한 줄 아래 세 줄이었다. 거기에 실제로 배열 경계 선언에서 '스펙트럼'의 일부를 사용했습니다. 물론 컴파일 타임에 크기가 지정되지 않았습니다 ... – canavanin

답변

2

전역 변수와 동일한 이름 (스펙트럼)을 갖는 지역 변수 (루틴 내 no_problem_here 및 문제)를 선언하는 것이 오류가 발생하기 쉬운 경우에도 코드 샘플에 오류가 표시되지 않습니다 모듈 non_buggy).

어떤 컴파일러를 사용하고 있습니까? ifort 11.1과 gfortran 4.7.0으로 샘플을 컴파일했다. (include와 end 모듈 사이에 명령어가 없다는 ifort가 불평하기 때문에 non_buggy 모듈의 키워드 CONTAINS에 주석을 달기 만하면된다.)

+0

시간과 노력에 감사드립니다! 나는 그 문제를 발견했다. 그것은 모듈 변수와 같은 이름을 가진 지역 변수와는 아무 상관이 없었습니다. 그것은 단순히 저에게 어리 석다는 것입니다 ...(원래의 질문 아래 내 의견을 참조하십시오) – canavanin

4

linux 및 osx에서 ifort 11로 재생할 수 없습니다. 나는 검증 할 수 없기 때문에 ifort 12가 없다.하지만 여기서 중요한 것은 모듈에서 spectrum을 내보내는 것이고, 이것은 가장 나쁜 아이디어 일 가능성이 높다. 모듈에 항상 private 키워드를 사용하고 내보내려는 내용 만 명시 적으로 공개하십시오.

스펙트럼을 모듈 변수로 만들려는 경우 (이해가 안되는 이유는 무엇입니까? 하나의 스펙트럼 만 예상합니까? 확실합니까?) save 키워드를 사용하여 값을 유지합니다.

마지막으로 모듈 변수의 그림자를 그립니다. 바보 같은 fortran은 네임 스페이스의 개념이 없습니다. 다른 모듈의 모듈에서 모든 것을 빼면 네가 네임 스페이스를 오염 시키므로 이러한 경우가 발생할 가능성이 큽니다. 어떤 경우에는 손상을 줄이기 위해 서브 루틴 가져 오기를 선호합니다 (의사 소통이 적어 지지만). 모듈 바를 최소한으로 유지하고, 할 때는 고유 한 접두어로 접두어를 붙이거나 단순히 사용하지 말고 코드의 OOP 레이아웃과 같은 방식으로 스스로를 규율하십시오.

모듈은 무 상태이어야합니다. 유연성과 멀티 쓰레딩 두통을 줄일 수 있습니다.

+0

그냥 추가 : 당신은 또한 당신이 "유형"자체처럼 당신이 정말로 원하는 것을 포함시키기 위해 "사용"문장에서 유일한 절을 사용할 수 있습니다. – haraldkl

+0

@Stefano : 어떤 경우에는 서브 루틴 가져 오기를 선호하여 피해를 줄이겠습니까? (의사 소통이 적어졌지만)? – bdforbes

+1

@bdforbes : 모듈 수준에서 모듈을 사용하는 대신 필요한 루틴을 각 루틴에 사용한다고 가정합니다. 모듈이 무엇을 사용하는지 보려면 현재 모듈의 초기 부분을 살펴 보는 대신 개별 루틴을 열어야하기 때문에 더 많은 중복이 발생할 수 있고 의사 소통이 어려워 질 수 있습니다. –