캐치

2013-09-05 5 views
2

Gfortran이 편리한 -ffpe-trap 컴파일러 옵션을 가지고 있지만 비슷한 옵션이 GCC 사용할 수 없습니다. 나는 그들이 예외를 다르게 처리한다는 것을 모호하지만, 단지 컴파일러 플래그를 사용 가능하게 설정하여 FPE에서 죽을 수있는 이유를 알 수는 없지만 다른 예외는 예외를 설정하는 추가 코드를 필요로합니다.캐치

+0

Fortran 2003에서 IEEE 예외 및 반올림 모드를 사용하여 C와 비슷한 기능을 수행 할 수 있습니다. gfortran은 아직 지원하지 않습니다. 예외를 잡기 위해 컴파일러 플래그가 사용 된 경우 해당 코드를 방해 할 수 있습니다. –

답변

3

죄송합니다. 진짜 대답은 바닥에 있습니다.

부동 소수점 예외는 컴파일러 플래그가 아닌 C99의 라이브러리 코드에 의해 제어됩니다. 다음은 예입니다 :

#include <fenv.h> 
#include <math.h> 
#include <stdio.h> 

#define PRINTEXC(ex, val) printf(#ex ": %s\n", (val & ex) ? "set" : "unset"); 

double foo(double a, double b) { return sin(a)/b; } 

int main() 
{ 
    int e; 
    double x; 

    feclearexcept(FE_ALL_EXCEPT); 

    x = foo(1.2, 3.1); 

    e = fetestexcept(FE_ALL_EXCEPT); 
    PRINTEXC(FE_DIVBYZERO, e); 
    PRINTEXC(FE_INEXACT, e); 
    PRINTEXC(FE_INVALID, e); 
    PRINTEXC(FE_OVERFLOW, e); 
    PRINTEXC(FE_UNDERFLOW, e); 

    putchar('\n'); 

    feclearexcept(FE_ALL_EXCEPT); 

    x += foo(1.2, 0.0); 

    e = fetestexcept(FE_ALL_EXCEPT); 
    PRINTEXC(FE_DIVBYZERO, e); 
    PRINTEXC(FE_INEXACT, e); 
    PRINTEXC(FE_INVALID, e); 
    PRINTEXC(FE_OVERFLOW, e); 
    PRINTEXC(FE_UNDERFLOW, e); 
    return lrint(x); 
} 

출력 :

FE_DIVBYZERO: unset 
FE_INEXACT: set 
FE_INVALID: unset 
FE_OVERFLOW: unset 
FE_UNDERFLOW: unset 

FE_DIVBYZERO: set 
FE_INEXACT: set 
FE_INVALID: unset 
FE_OVERFLOW: unset 
FE_UNDERFLOW: unset 

업데이트 :

#pragma STDC FENV_ACCESS on 

#define _GNU_SOURCE 
#include <fenv.h> 

int main() 
{ 
#ifdef FE_NOMASK_ENV 
    fesetenv(FE_NOMASK_ENV); 
#endif 

    // ... 
} 
: GNU GCC를 사용하면 선택적으로 트랩에 소수점 예외 부동의 원인과 신호를 보낼 수 있습니다

그러나 잘못된 지침을 실행 취소 할 수 없기 때문에 SIGFPE를받을 때해야 할 일이 무엇인지 명확하게 밝히지는 않았습니다 엔. (그리고 Pragma에 대한 @ EricPostpischil의 견해를 참조하십시오; thanks!)

+0

나는 이것이 어떤 식 으로든 OP의 질문에 대답한다고 생각하지 않습니다. OP가 * 왜 * gfortran에게 FPE에 대한 플래그가 있고 gcc가 아닌지 묻습니다 * C에서 FPE에 플래그를 지정하는 방법이 아닙니다. –

+0

@KyleKanos : 네 말이 맞아. 나는 내가 무엇을 찾고 있는지 완전히 모르겠다. 그러나 지금 나는 그것을 발견했다. 업데이트 됨. –

+1

부동 소수점 환경에 액세스하거나 기본값이 아닌 부동 소수점 제어 모드에서 실행되는 코드는 '#pragma STDC FENV_ACCESS on'을 사용하여 구현을 알려야합니다. 그렇지 않으면 C 표준에 따라 동작이 정의되지 않습니다. –