2014-01-07 81 views
0

嗨,我想問一下關於setjmp/longjmp。我試圖尋找,但我unsucessuful ...兩個獨立的jmp_bufs如何工作?

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

jmp_buf a, b; 

void jump() { 
    int aa = setjmp(a); 

    if (aa) 
    { 
     printf("Jump!\n"); 
    } 
    else 
    { 
     longjmp(b, 1); 
     printf("Should not happened...\n"); 
    } 

    printf("End of function!\n"); 
} 


int main(int argc, char** argv) { 
    int bb = setjmp(b); 

    if (bb) 
    { 
     longjmp(a, 1); 
     printf("Should not happened...\n"); 
    } 
    else 
    { 
     jump(); 
     printf("What here?\n"); 
    } 

    printf("Exit\n"); 
    return 0; 
} 

的問題是,最後的printf後會發生在跳躍()什麼......我想這個代碼,並將其變成無限循環。爲什麼?我雖然setjmp將存儲環境數據,所以跳轉功能應在原始調用後返回...我很安靜困惑。感謝您的回覆:)

回答

2

整個程序有未定義的行爲。

  1. setjmp(b);存儲堆棧狀態。
  2. jump()被調用。
  3. `setjmp(a);'再次存儲堆棧狀態。
  4. longjmp(b, 1);將堆棧恢復到之前調用jump()之前的時間點。因此,存儲在a中的狀態現在無效。
  5. 繼續執行if,main()
  6. longjmp(a, 1);被調用。哎喲。這會導致由於上述4而導致的未定義行爲。

您的困惑可能是由於在Linux文檔中對setjmp()的世界「return」稍微不精確的使用造成的。

如果調用setjmp()的函數返回,則堆棧上下文將失效。

在你的榜樣,功能jump()沒有以正常的方式返回,但效果是一樣的:堆棧被「斬」第一longjmp()的狀態jump()之前,這是一個回報也是。

+0

謝謝。你知道一些有用的頁面或文獻,我可以找到關於C和堆棧的更多信息嗎?也許我對它的想象與現實稍有不同:) – jirizaj