2012-09-09 4 views
1

setjmp (jmp_buf) 및 longjmp (jmp_buf, int)를 사용하여 예외 처리에 대한 this article 읽기를 시작했습니다. 그래서 기본적으로 xRecord 유형의 지역 변수를 사용하는 링크 된 목록을 작성하고이를 목록에 연결합니다. (예 2) 잘 작동합니다. 그러나 예제 3에서는 매크로 (XTRY 및 XEND)로 단계가 요약됩니다.열기 및 닫기 태그가있는 C 매크로입니까?

#define DIVIDE_BY_ZERO -3 
    int SomeFunction(int a, int b) 
    { 
     if (b == 0) // can't divide by 0 
     XRaise(DIVIDE_BY_ZERO); 
     return a/b; 
    } 

    void main(void) 
    { 
     XRecord XData; 
     XLinkExceptionRecord(&XData); 
     switch (setjmp(XData.Context)) 
     { 
     case 0: // this is the code block 
      { 
       int Result = SomeFunction(7, 0); 
       // continue working with Result 
      } 
      break; 
     case DIVIDE_BY_ZERO: 
      printf("a division by zero occurred\n"); 
      break; 
     default: 
      printf("some other error occurred\n"); 
      break; 
     case XFINALLY: 
      printf("cleaning up\n"); 
     } 
     XUnLinkExceptionRecord(&XData); 
    } 

예 3 :

void main(void) 
    { 
     XTRY 
     case XCODE: // this is the code block 
      { 
       int Result = SomeFunction(7, 0); 
       // continue working with Result 
      } 
      break; 
     case DIVIDE_BY_ZERO: // handler for a 
           specific exception 
      printf("a division by zero occurred\n"); 
      break; 
     default: // default handler 
      printf("some other error occurred\n"); 
      break; 
     case XFINALLY: // finally handler 
      printf("cleaning up\n"); 
     XEND 
    } 

내 질문은 무엇 나를 가장 자극하는 것은 예 2의 실제 switch 문은 단지

3에 예 2 "사라"이다 , 어떻게 이러한 "열리고 닫는"매크로를 만들 수 있습니까? 당신은 두 가지 예를 비교하고, 매크로가 있어야한다 무엇을, C 매크로는 간단한 텍스트 대체 있다는 사실을 유지하는 경우

+3

오른쪽. 그래서 당신의 질문은 무엇입니까? –

+1

... 질문은 무엇입니까? – Vlad

+0

어,하지 마세요. C에서 블록의 텍스트 구조를 변경하는 매크로는 절대로 생성하지 않습니다. C의 블록은'{} '에 의해 제공됩니다. 그런 일은 절대로 필요하지 않습니다. 그 주위에'{}'를 넣으십시오. –

답변

1

는 분명하다 :

#define XTRY XRecord XData; \ 
       XLinkExceptionRecord(&XData); \ 
       switch (setjmp(XData.Context)) \ 
       { 

#define XEND } \ 
       XUnLinkExceptionRecord(&XData); 

참고 \의 사용이 매크로가 더 걸쳐 수 있도록 한 줄 이상.

또한 연속 매크로의 배수를 사용하는 때문에 변수 XData의 여러 정의에 오류를 제공하지 않도록, 매크로가 열려 있고 ({}을 추가하여) 새로운 범위를 종료 할 수 있습니다. do/while(0) trick을 사용하면 이러한 매크로를 문제없이 직접 if, for 등에 넣을 수 있습니다.

+0

고마워, 내가 알 필요가있는 것만! – Redweasel

1

{}을 숨기지 말고 문제가됩니다.

#define MY_BLOCK           \ 
for (int once = 0; once < 1; ++once)      \ 
    for (XRecord XData = { 0 }; once < 1; ++once)   \ 
    for (XLinkExceptionRecord(&XData); (XUnLinkExceptionRecord(&XData), (once < 1)); ++once) \ 
     switch (setjmp(XData.Context)) 

혜택이 만 대신 두 개의 매크로를 필요로 할 것, 그리고 {} 명확를 나타냅니다하십시오 C99 준수 컴파일러, 당신은 지역 변수와 이전과 블록 후에 실행되는 일부 코드를 숨길 수 있습니다 좋아하는 편집기의 경우에도 구문의 범위.

+0

나는 그것을 보았고 귀하의 게시물을 게시하기 바로 전에 내 코멘트를 삭제했습니다. 그러나 이것은 여전히 ​​지나치게 모호 해 보인다. – interjay

+0

은 처음부터 'XTRY' /'XEND' 아이디어보다 난독 화되지 않습니다. –

+0

사실, 그렇 겠지. 끝 매크로가 필요하지 않습니다 * 멋진 터치입니다. – interjay