2010-05-23 3 views
30

언어 참조 (Intel 's)의 항목을 읽었지만 그 내용을 이해할 수는 없습니다. 평신도의 용어로 누군가가 나에게 설명 할 수 있었 을까? 그것이 모듈에 포함될 때의 의미는 무엇인가?fortran SAVE statement

+0

http://stackoverflow.com/questions/2582409/are-local-variables-in-fortran-77-static-or-stack-dynamic/2583248 –

+7

매우 좋은 답변을 보완하기 위해, 내 추천은 : "절대로 저장하지 마십시오"입니다. 재난을 대비하는 방법이며 일상적으로 쓰레드를 안전하지 않고 무국적으로 만들지 않습니다. 저장을 사용하는 이유가있을 수 있지만 매우 드물고 다른 프로그래밍 스타일 또는 솔루션을 사용하여 동일하게 수행 할 수 있습니다. –

답변

37

원칙적으로 모듈이 범위를 벗어날 경우 해당 모듈의 변수는 정의되지 않습니다. SAVE 특성으로 선언되거나 SAVE 문이 사용되는 경우는 예외입니다. "정의되지 않음"은 모듈을 다시 사용하면 이전 값을 가진 변수에 의존 할 수 없음을 의미합니다. 모듈에 다시 액세스 할 때 이전 값을 가질 수도 있고 그렇지 않을 수도 있습니다. . 그러나 많은 컴파일러는 모듈 변수에 대해 이렇게하지 않습니다. 변수는 아마도 그 값을 유지합니다. 컴파일러가 모듈이 범위 내에 있는지 그리고 모듈 변수가 처리되는지 여부를 파악할 가치가 없습니다. 전역 변수로서 - 그러나 그것에 의존하지 마십시오! 안전을 위해, 메인 프로그램에서 모듈을 "저장"하거나 "사용"하여 범위를 벗어나지 않도록하십시오. 등, "제 호출"초기화 카운터

subroutine my_sub (y) 

integer :: var 
integer, save :: counter = 0 
logical, save :: FirstCall = .TRUE. 

counter = counter + 1 

write (*, *) counter 

if (FirstCall) then 
    FirstCall = .FALSE. 
    .... 
end if 

var = .... 
-

"저장"서브 루틴 또는 함수 (@ire_and_curses 의해 작성된)의 호출을 통해 "상태"를 저장하는 것도, 절차 중요

이 코드 조각에서 "카운터"는 서브 루틴 x의 호출 수를보고합니다. 실제로 Fortran> = 90에서 선언문의 초기화는 "저장"을 의미하기 때문에 "저장"을 생략 할 수 있습니다.

현대의 컴파일러에서는 save 속성이나 declaration-on-a-declaration 없이는 프로 시저의 로컬 변수가 호출을 통해 값을 잃는 것이 정상입니다. 따라서 해당 호출에서 다시 정의하기 전에 나중에 호출 할 때 "var"를 사용하려고하면이 값은 정의되지 않고 이전 프로 시저 호출시 계산 된 값이 아닐 것입니다.

이것은 많은 FORTRAN 77 컴파일러의 동작과 다른데, 일부는 모든 로컬 변수의 값을 유지하지만 언어 표준에서는 필요하지 않습니다. 일부 오래된 프로그램은이 비표준 동작에 의존하여 작성되었습니다.이 프로그램은 최신 컴파일러에서 실패합니다. 많은 컴파일러는 비표준 동작을 사용하고 모든 로컬 변수를 "저장"하는 옵션을 가지고 있습니다. (가) 속성을 저장하지만이 있어야 지역 변수의 잘못된 사용법을 보여줍니다 코드 예제와 업데이트하지 않습니다 : 서브 루틴의

module subs 

contains 

subroutine asub (i, control) 

    implicit none 

    integer, intent (in) :: i 
    logical, intent (in) :: control 

    integer, save :: j = 0 
    integer :: k 

    j = j + i 
    if (control) k = 0 
    k = k + i 

    write (*, *) 'i, j, k=', i, j, k 

end subroutine asub 

end module subs 

program test_saves 

    use subs 
    implicit none 

    call asub (3, .TRUE.) 
    call asub (4, .FALSE.) 

end program test_saves 

지역 변수 K가 의도적으로 LATER 편집이

오용 -이 프로그램에서는 컨트롤이 TRUE이지만 첫 번째 호출에서 초기화되지만 두 번째 호출에서는 컨트롤이 거짓이므로 k은 재정의되지 않습니다.그러나 저장 속성없이 k은 정의되어 있지 않으므로 해당 값을 사용하는 것은 불법입니다.

gfortran와 프로그램을 컴파일, 내가 K 어쨌든 그 값을 유지 것을 발견 :

i, j, k=   3   3   3 
i, j, k=   4   7   4 

:

i, j, k=   3   3   3 
i, j, k=   4   7   7 

이 ifort 공격적인 최적화 옵션을 사용하여 프로그램을 컴파일, k는 그 값을 잃었다 디버깅 옵션과 함께 ifort를 사용하면 문제가 런타임에 감지됩니다!

i, j, k=   3   3   3 
forrtl: severe (193): Run-Time Check Failure. The variable 'subs_mp_asub_$K' is being used without being defined 
+0

아마도 C의 "정적 인"키워드와 같은 것이라고 언급 할 가치가 있습니다. – MasterHD

+0

_ 주 프로그램의 모듈을 "사용"하여 scope_에서 벗어나지 않도록합니다. 이제는 필자가 글을 쓸 때 아무런 문제가 없었던 이유를 알았습니다. 내 프로그램에서 단 하나의'SAVE '도! 고맙습니다! –

3

보통 로컬 변수는 실행이 현재 프로 시저를 벗어나면 범위를 벗어나기 때문에 이전 호출에서 해당 값의 '메모리'가 없습니다. SAVE은 프로 시저의 변수가 한 호출에서 다음 호출로 그 값을 유지하도록 지정하는 방법입니다. 프로 시저에 상태를 저장하려는 경우 (예 : 누적 합계를 유지하거나 변수의 구성을 유지하려는 경우) 유용합니다.

예를 들어 good explanation here이 있습니다.

+0

음, 그 예를 들려 주시겠습니까? 모듈에서 SAVE를 선언하면 변수가 서브 루틴의 값을 변경할 수 없습니다. –

+0

@Friedrich Schwartz : 아닙니다. 새 값을 설정할 수도 있지만 변수를 설정하기 전에 변수 값을 검사하는 경우 변수를 설정 한 마지막 값이 표시됩니다. 'SAVE'가 없으면 'undefined'가 보일 것입니다. 간단한 예제를 통해 작업하면보다 명확하게 이해할 수 있습니다. –

4

M.S.B에 대한 답변으로 게시. 의견에 서식이 없기 때문에 돼지의 아침 식사를으로 만들 수 있습니다.

먼저 답장을 보내 주셔서 감사합니다. 감사합니다.

내가 제대로 이해한다면;

subroutine save(j) 
    implicit none  

    integer :: i = 0, j 
    save i 

    i = i + j 
    write(*,*)i 

    end subroutine save 


    program test_save 
    implicit none 

    integer :: j 

    j = 1 

    call save(j) 
    call save(j) 

    end program test_save 

위의 작은 예에 SAVE 문을 위해 그것을하지 않았다, i 변수 (변수의 값) 서브 루틴을 저장의 첫 번째 호출 후 "손실"될 것이다. 덕택에이 값은 "1"로 유지되고 두 번째 호출에서는 "2"로 증가합니다.

내가 맞았습니까? 아마 근처에?

+4

예, SAVE 문은 변수 i가 해당 값을 유지하도록합니다. 이 예에서 Fortran 90에서는 save 문이 선택적입니다. "i"가 선언에서 초기화되었으므로 "save"가 자동으로 적용됩니다. FORTRAN 77에서는 save 문이 필수입니다. –

2

간략한 설명은 다음과 같습니다. save 속성은 동일한 서브 루틴/함수에 대한 다른 호출에서 변수의 값을 보존해야한다고 말합니다. 그렇지 않으면 일반적으로 서브 루틴/함수에서 복귀 할 때 "로컬"변수는 해당 변수가 저장된 메모리가 해제되므로 해당 값을 잃게됩니다. 이 언어를 아는 경우 C에서 static과 같습니다.