SIGFPE의 신호 처리기에서 돌아 왔을 때, 변수 i는 내 프로그램에서 올바른 결과를 얻으려는 것보다 하나가 작습니다 (모든 것을 반복합니다). 쌍 배열의 쌍) 신호 "catch"에서 돌아 오는 경우 sigsetjmp의 반환 값을 확인하고 i를 증가시켜야합니다. 왜 이런거야? 부동 소수점 예외의 반복 과정에서 발생하는 증분이 손실되는 이유는 무엇입니까?리눅스에서 C가있는 sigsetjmp의 모호한 문제
#include <stdio.h>
#include <signal.h>
#include <stdlib.h>
#include <setjmp.h>
jmp_buf e;
int i;
void float_exception();
int main()
{
int pairs[][2] = {
{10, -5}, {10, -3}, {-10, -3}, {-10, -5}, {-10, 3}, {-10, 5}, {-10, 0},
{10, 0}, {0, 10}, {2, 3}, {3, 3}, {5, 10}
};
int npairs;
/* handle sigfpe so /0 doesn't interrupt the rest of the program */
signal (SIGFPE, float_exception);
printf ("Seeing what my C implementation does with negative or 0 modulo"
"\narithmetic.\n");
npairs = sizeof (pairs)/sizeof (int)/2;
i = 0;
if (sigsetjmp (e, 1) != 0) {
i++; /* without this line, i is one less than I expect it to be */
}
for (; i < npairs - 1; i++) {
printf ("%d: %d %% %d\t= ", i, pairs[i][0], pairs[i][1]);
fflush (stdout);
printf ("%d\n", pairs[i][0] %pairs[i][1]);
fflush (stdout);
}
return 0;
}
void float_exception()
{
printf ("fpe\n");
fflush (stdout);
longjmp (e, 1);
}
나는 아무 소용 내가 휘발성를 선언 시도했다, 나는 카페의 대답은 바로 너무 생각입니다. 긴/sigset/JMP 내가 찾을 수있는 유일한 일이었다 나를 콜백 함수에서 뛰어 내리고 루프로 돌아 가게 할 것입니다. 그렇지 않으면 예외가 계속 반복해서 신호를 계속 방출합니다 (0으로 나누기 때문에 정말 놀랍지는 않습니다). 그리고 그 루프에서 벗어나기 위해서 저는 신호 처리기에서 다른 코드 블록으로 이동할 필요가있다. float_execption() stdio 주위에 뮤텍스를 사용할 수있을 것 같아요. –
신호 처리기 내에서 signal()을 제외한 * 모든 * 라이브러리 함수를 호출하는 것은 위험합니다. 우리가 신호 처리기에서 printf()를 호출했지만 콘솔에 메시지를 쓰는 대신 부분적으로 o를 덮어 썼습니다. f. 우리가 업데이트 한 Access .mdb 파일. 복구 할 수 없을 정도로 데이터베이스가 손상되었습니다. 솔직히 C는 이와 같은 예외 처리에 아주 좋은 도구를 제공하지 않습니다. 작업을 시도하기 전에 인수에 대한 온 전성 검사를하는 것이 훨씬 낫습니다. –
@Ringding, 0으로 나눈 값은 정의되지 않은 동작이므로 Tom은 신호가 발생한다는 것을 전혀 보증하지 않습니다 (C 표준에 의해 제공됨, POSIX 표준은 보장 할 수는 없지만). 또 다른 것은 당연히 i의 가치가 점프를 가로 질러 저장되는 것이 보장되지 않는다는 것입니다. i의 값은 지정되지 않습니다. 그래서 휘발성이 필요합니다. 그의 프로그램은 정의되지 않은 행동과 알려지지 않은 값에 의존합니다. 그러나 하루가 끝날 때,이 프로그램은 Standard의 PDF가 아닌 구현으로 실행됩니다. 따라서 그 사람이 자신이하는 일을 잘 안다면 그는 괜찮습니다. –