2012-07-13 3 views
2

나는 포트란 코드를위한 커스텀 프리 프로세서가있는 환경에서 작업한다. 전 프로세서를 사용하여 논리적 인 매개 변수를 일종의 가난한 사람의 함수 포인터로 토글합니다. , 즉gfortran 컴파일러 버그?

program main 
    logical,parameter :: untrue=.false. 
    if(untrue)then 
    call func1() 
    else 
    call func2() 
    endif 
    end 

    subroutine func2() 
    print*,"Hello, World!" 
    end 

func1 어디서나 정의되지 않지만 아마도 컴파일러가 떨어져 그 전화를 최적화하기 때문에,이 gfortran (버전 4.4 및 4.6)와 컴파일 : 나는이 유사한 상황을 한 것으로 오늘 깨달았다. 나는 현재 다른 컴파일러를 가지고 있지 않습니다.이 코드는 다른 곳에서 컴파일합니까? 수/이것은 컴파일러 버그로 간주 될 수 있습니까?

논리 스위치를 전환하는 이유 중 일부는 (코드 포함/포함하지 않음) 컴파일러가 해당 코드 블록 내에서 인터페이스/구문 (가능한 경우)을 검사 할 수 있도록하는 것입니다. 간단한 함수 호출이 아닙니다.) 이것은 테스트가 수행되지 않고 링커가 함수를 요구하지 않는다는 것을 의미합니까?

답변

6

이것은 컴파일러 버그가 아닙니다. 참조 된 외부 서브 프로그램이 없다는 것은 표준에서 Fortran 프로세서가 진단하도록 요구하는 것이 아닙니다. 다른 프로세서는 불평 할 수도 있고하지 않을 수도 있습니다. 최적화 설정과 같은 것들이 결과에 영향을 미칠 수 있습니다 - 인텔 포트란 12.1.5는 최적화 기능을 끄고 최적화에 불평하지 않습니다.

예제 코드에서 func2는 외부 서브 프로그램이고, 프로그램 단위에 대한 Fortran의 별도 컴파일 모델은 프로 시저 인터페이스 점검이 필요 없음을 의미합니다. 많은 프로세서를 사용하면 실제로는 일어나지 않을 것입니다 (실제로 func2는 메인 프로그램 이후에 오랫동안 컴파일 된 별도의 파일에있을 수 있습니다. 아마도 메인 프로그램의 소스가 더 이상 제공되지 않는 상황에서 다른 시스템에있을 수 있습니다) . 프로 시저 인터페이스 검사를 보장하려면 프로 시저에 명시 적 인터페이스 (예 : 모듈에 넣음)가 있는지 확인해야합니다. Fortran 2003 표준에서 소개되고 gfortran 4.6에서 지원되는 프로 시저 포인터 언어 기능이 도움이 될 수 있습니다.

+0

감사합니다. 이 시점에서 표준의 새로운 개정판에 의존 할 수는 없습니다. 코드는 15 년 전에 작성되었으며 프리 프로세서를 사용하여 많은 f90 구조가 인터페이스를 필요로하는 프로 시저 검사에 대해서도 알고 있습니다.하지만 다시 말해서 우리 사전에 의해 지원되지 않습니다. - 프로세서. 표준은 dead-code 문제를 다루지 않기 때문에, 아무 것도 ... 고마워요. (아무에게도 이것에 대해 아무 말도 할 수 없도록 잠시 기다릴 것입니다. do not, 나는 기꺼이 이것을 받아 들일 것이다. 어느 쪽이든 좋은 대답을 +1하라.) – mgilson

1

여기서 볼 수있는 것은 컴파일러가 단순히 호출되지 않는 참조를 무시할 수 있도록 허용하는 것입니다. 라인 : 당신의 if 블록의 첫 번째 부분은 실행하지 않을 것을

logical,parameter :: untrue=.false. 

보장합니다. IanH이 지적했듯이 (+1), 이것은 컴파일러 버그가 아니며 최적화 프로세스의 일부입니다. 이 코드는 기본 최적화가 pgf90 10.6-0ifort 12.0.2.137으로 컴파일됩니다. 그러나 최적화가 활성화되지 않은 상태에서 컴파일하도록 지시하면 실패합니다.

당신의 선은 말한다 그러나 경우 : 그것은 변수 untrue이 값을 변경할 수대로 컴파일러는 불평에 대한 가능성이

logical :: untrue=.false. 

. 예를 들어, 높은 최적화 레벨이 필요하지 않으면 pgf90은 실패하지만 'ifort'는 여전히 기본 최적화 레벨에서 컴파일됩니다.

어떤 경우 든 컴파일러 동작에 의존하는 것이 가장 바람직하지 않으며, 지적한 바와 같이 항상 모듈을 사용하여 외부 함수 및 서브 루틴 인터페이스를 지정하는 것이 가장 좋습니다.

+0

'ifort'의 기본 최적화 수준은'O2'입니다 :) –

2

최적화 수준이 O0 인 경우에도 도달 할 수없는 코드 섹션을 제거하는 GNU Fortran의 특정 동작 인 것으로 보입니다. 이는 ISO/IEC 1539 : 1991 : §8.1.2와 일치하여 IF 구문 중 단 하나만 블록을 실행해야한다는 것과 §8.1.1을 말합니다.2는 블록 외부에서 블록 내부로 제어를 전송하는 것을 명시 적으로 금지합니다. 이렇게하면 컴파일러는 코드 섹션을 제거하고 프로그램 소스를 다시 컴파일하지 않고 예제에서 IF 구문의 동작을 변경할 수 없으므로 컴파일러가 심볼을 잘 알고 있기 때문에 코드 섹션을 제거 할 수 있습니다.

그러나 나는 여전히 -Wall -Wunreachable-code으로 컴파일 할 때 도달 할 수없는 코드에 대해 경고하지 않는다는 것이 이상하다고 생각합니다.

관련 문제