我想使用 longjmp 返回错误代码,并从调用 setjmp 的函数传递它。简化代码:
int do_things(stuff ........)
{
int error_code;
jmp_buf jb;
if ((error_code = setjmp(jb)) == 0) {
/* do stuff */
return 0;
}
else {
return error_code;
}
}
Run Code Online (Sandbox Code Playgroud)
但我读到:“setjmp 宏的调用只能出现在以下上下文之一中:”
the entire controlling expression of a selection or iteration statement
if (setjmp(jb)) {
switch (setjmp(jb)) {
while (setjmp(jb)) {
Run Code Online (Sandbox Code Playgroud)
或者
one operand of a relational or equality operator with the other operand
an integer constant expression, with the resulting expression being
the entire controlling expression of a selection or iteration statement
if (setjmp(jb) < 3) {
Run Code Online (Sandbox Code Playgroud)
或者
the operand of a unary ! operator with the resulting
expression being the entire controlling expression of a
selection or iteration statement
if (!setjmp(jb)) {
Run Code Online (Sandbox Code Playgroud)
或者
the entire expression of an expression statement (possibly cast to void).
setjmp(bf);
Run Code Online (Sandbox Code Playgroud)
有没有好的方法获取返回值?(不使用switch,并case为所有可能的值编写 a )
编辑
感谢 Matt 在 c99 基本原理中找到了它。我现在想出的是:
int do_things(stuff ........)
{
volatile error_code;
jmp_buf jb;
if (setjmp(jb) == 0) {
working_some(&error_code, ....);
working_again(&error_code, ....);
working_more(&error_code, ....);
working_for_fun(&error_code, ....);
return 0;
}
else {
general_cleanup();
return error_code;
}
}
Run Code Online (Sandbox Code Playgroud)
又多了一个变量,看起来不太好......
从C99的基本原理来看:
对 setjmp 提出的一项要求是它可以像任何其他函数一样使用,即它可以在任何表达式上下文中调用,并且无论 setjmp 返回是直接返回还是通过调用 longjmp,表达式都可以正确计算。不幸的是,作为传统被调用函数的 setjmp 的任何实现都无法充分了解调用环境来保存在表达式求值过程中使用的任何临时寄存器或动态堆栈位置。(setjmp 宏似乎仅在扩展为内联汇编代码或对特殊内置函数的调用时才有帮助。)临时变量在对 setjmp 的初始调用上可能是正确的,但不太可能在由对 longjmp 的相应调用。这些考虑因素决定了 setjmp 只能从相当简单的表达式中调用,而不太可能需要临时存储。
C89 委员会考虑的另一个建议是要求实现认识到调用 setjmp 是一种特殊情况,因此他们采取一切必要的预防措施,在 longjmp 调用时正确恢复 setjmp 环境。该提议被拒绝,理由是一致性:目前允许实现专门实现库函数,但没有其他情况需要特殊处理。
我对此的解释是,它被认为限制性太大,无法指定a = setjmp(jb);必须有效。因此标准未对其进行定义。但特定的编译器可能会选择支持这一点(并希望能够记录下来)。为了便于移植,我想您应该使用一些预处理器检查来验证代码是否是使用已知支持此功能的编译器进行编译的。
| 归档时间: |
|
| 查看次数: |
1184 次 |
| 最近记录: |