1

setjmp(jmp_buf)とlongjmp(jmp_buf、int)を使用したcでの例外処理に関するこの記事を読み始めました。したがって、基本的に、タイプxRecordのローカル変数を使用してリストにリンクするリンクリストを作成します。(例2)問題なく動作します。ただし、例3では、ステップがマクロ(XTRYおよびXEND)に要約されます。私を最も苛立たせているのは、例2の実際のswitchステートメントが3で「消えた」ということです。

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

私の質問は、これらの「開閉」マクロをどのように構築できるかということです。

4

2 に答える 2

1

2つの例を比較し、Cマクロは単純なテキスト置換であることに注意すると、マクロが何であるかは明らかです。

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

#define XEND  } \
              XUnLinkExceptionRecord(&XData);

\を使用して、マクロが複数の行にまたがることを許可することに注意してください。

また、マクロを開いたり閉じたりして(とを追加{して})、マクロを連続して複数使用しても、変数の定義が複数あるためにエラーが発生しないようにすることもできますXData。このdo / while(0)トリックifを使用して、これらのマクロを、、などの内部に問題なく直接配置できるようにすることもできforます。

于 2012-09-09T15:38:57.023 に答える
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))

利点は、必要なマクロが2つではなく1つだけであり{}、お気に入りのエディターであっても、構成の範囲を明確に示すことです。

于 2012-09-09T16:01:01.630 に答える