我刚开始阅读关于使用setjmp(jmp_buf)和longjmp(jmp_buf,int)在c中处理异常的this article。所以我基本上构建了一个链表,它使用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
}
我的问题是,如何构建这些“打开和关闭”宏?
最佳答案
如果比较这两个示例,并记住C宏是简单的文本替换,那么宏应该是什么是显而易见的:
#define XTRY XRecord XData; \
XLinkExceptionRecord(&XData); \
switch (setjmp(XData.Context)) \
{
#define XEND } \
XUnLinkExceptionRecord(&XData);
注意使用
\
允许宏跨越多行。您可能还希望宏打开并关闭一个新的作用域(通过添加
{
和}
),以便连续使用宏multiple不会由于变量XData
的多个定义而产生错误。您也可以使用do / while(0)
trick来允许这些宏直接放置在if
、for
等内部而不会出现问题。