2017-08-06 87 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

謝謝,我沒有意識到我的代碼有其他未定義的行爲。 –