2012-09-09 51 views
1

我剛剛開始閱讀關於使用setjmp(jmp_buf)和longjmp(jmp_buf,int)在c中進行異常處理的this article。所以我基本上構建了使用xRecord類型的局部變量並將其鏈接到列表的鏈接列表。 (例2)它工作得很好。但在示例3中,這些步驟彙總爲宏(XTRY和XEND)。什麼最讓我惱火的是,例如2的實際switch語句只是在3, 「消失」帶開啓和關閉標籤的C宏?

例2:

#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 
    } 

我的問題是,我如何構建這些「開放和關閉」宏?

+3

沒錯。那麼你的問題是什麼? –

+1

...問題是? – Vlad

+0

呃,不要這樣做。從來沒有發明過改變C文本結構的宏.C中的塊由'{}'給出。從來沒有需要這樣的事情。只需在其周圍放置「{}」即可。 –

回答

1

如果你比較兩個例子,記住,C宏是簡單的文本替換時,宏應該是什麼是顯而易見的:

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

#define XEND } \ 
       XUnLinkExceptionRecord(&XData); 

注意使用\允許宏跨越多個比一行。

您可能還需要有宏打開和關閉一個新的作用域(加入{}),使連續使用宏多個不因變量XData的多個定義給出一個錯誤。您也可以使用do/while(0) trick來允許這些宏直接放置在iffor等之內,沒有問題。

+0

非常感謝,正是我需要知道的! – Redweasel

1

不要隱藏{}這隻會造成麻煩。隨着C99標準的編譯器,你可以隱藏局部變量,即前後塊後執行一些代碼:

#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)) 

好處是,你只需要一個宏觀的而不是兩個,和{}會明確註明構造的範圍,即使是你最喜歡的編輯器。

+0

我看到了這一點,並在發佈你的消息之前刪除了我的評論。但是這似乎仍然過度混淆。 – interjay

+0

從一開始就不比'XTRY' /'XEND'想法更混亂。 –

+0

是的,我想。不需要最終宏*是一個很好的接觸。 – interjay