2017-08-06 20 views
2

的setjmp的(3)文档(我的系统上)使用的setjmp指出在包装功能和局部变量在联机手册重挫

所有可访问对象有值作为时间的longjmp的()函数被调用除了在setjmp()调用和longjmp()调用之间更改的不具有易失性类型且已被更改的自动存储调用持续时间的对象的值不确定。

这是否仅包括在相同的范围,因为在职能范围内调用setjmp,或者也可以是任何物体了调用堆栈更高功能的对象?

例如,以下代码是否正确?

#include <stdio.h> 
#include <setjmp.h> 

jmp_buf env; 

void function_that_longjmps(void) 
{ 
    longjmp(env, 1); 
} 

int setjmp_wrapper(jmp_buf env) 
{ 
    if (setjmp(env) == 0) 
     return 0; 
    else 
     return 1; 
} 

int main() 
{ 
    int i = 0; 

    if (setjmp_wrapper(env) == 0) { 
     i = 1; 
     function_that_longjmps(); 
    } 

    printf("i = %d\n", i); 
    return 0; 
} 

局部变量i获取setjmplongjmp调用之间修改,但它并没有在setjmp_wrapper的范围存在。在这种情况下,变量是否有可能被破坏?

+1

尝试'longjmp'到'setjmp_wrapper'已经返回后是未定义的行为本身。 – user2357112

回答

4

无论局部变量发生了什么,您的示例都会显示未定义的行为,因为您无法将longjmp转换为已返回的函数执行。

至于不呈现UB一个例子,也许

#include <stdio.h> 
#include <setjmp.h> 

jmp_buf env; 

void calls_longjmp(int *p) { 
    *p = 1; 
    longjmp(env); 
} 
void calls_setjmp(int *p) { 
    if (setjmp(env)) { 
     return; 
    } 
    calls_longjmp(p); 
} 
int main(void) { 
    int x = 0; 
    calls_setjmp(&x); 
    printf("%d\n", x); 
} 

然后x保证具有值1,不0或不确定时,longjmp后。引述C11 N1570 draft

所有可访问对象有价值观和抽象机249)的所有其它部件都状态,随着时间的longjmp函数被调用时,除了自动存储的对象的值持续时间为,它们包含调用相应setjmp宏的函数,这些函数没有volatile限定类型,并且在setjmp调用和longjmp调用之间进行了更改,这些都是不确定的。

+0

谢谢,我没有意识到我的代码有其他未定义的行为。 –