![](/img/trans.png)
[英]Why does the setjmp/longjmp crash on MSVC when it didn't in MinGW?
[英]Why does setjmp/longjmp
我想使用 setjmp/longjmp 在主函數中重用一些代碼(注意:這只是一個練習,而不是我在現實世界中認真計划做的事情)。 以下代碼是我想出的:
#include <stdio.h>
#include <setjmp.h>
jmp_buf jmp_body, jmp_ret;
void func(void)
{
if (setjmp(jmp_ret) == 0)
longjmp(jmp_body, 1);
}
int main()
{
int x = 0;
if (setjmp(jmp_body) == 1) {
printf("Body %d\n", ++x);
longjmp(jmp_ret, 1);
}
func();
func();
func();
return 0;
}
我期望此代碼的工作方式如下:
main()
函數將記住“body”部分的位置並使用if (setjmp(jmp_body) == 1)
跳過它。if (setjmp(jmp_ret) == 0)
記住主體應該返回的位置后, func()
調用將使用longjmp(jmp_body)
臨時跳轉到主體longjmp(jmp_ret, 1)
跳轉回func()
調用func()
main()
將按預期返回main()
。因此,我期望打印的代碼如下:
Body 1
Body 2
Body 3
相反,它永遠循環不斷地執行主體,這向我表明func()
調用沒有返回它應該返回的位置,而是可能返回到它自己之上,一遍又一遍地執行自己。
相比之下,以下代碼打印的正是我所期望的:
#include <stdio.h>
#include <setjmp.h>
jmp_buf jmp_body, jmp_ret;
int main()
{
int x = 0;
if (setjmp(jmp_body) == 1) {
printf("Body %d\n", ++x);
longjmp(jmp_ret, 1);
}
if (setjmp(jmp_ret) == 0)
longjmp(jmp_body, 1);
if (setjmp(jmp_ret) == 0)
longjmp(jmp_body, 1);
if (setjmp(jmp_ret) == 0)
longjmp(jmp_body, 1);
return 0;
}
將if (setjmp(jmp_ret) == 0) longjmp(jmp_body, 1)
放在使原始方法無效的函數調用中是什么意思?
TL/DR - 你不能跳回你跳出的函數。
7.13.2.1C 2011 在線選秀longjmp
函數
...
2longjmp
函數使用相應的jmp_buf
參數在程序的同一調用中恢復最近一次調用setjmp
宏所保存的環境。 如果沒有這樣的調用,或者如果調用來自另一個執行線程,或者如果包含setjmp
宏調用的函數在中間終止了執行248) ,或者如果setjmp
宏的調用在具有可變修改類型和執行的標識符的范圍在此期間離開了該范圍,行為是 undefined 。
248) 例如,通過執行 return 語句或因為另一個longjmp
調用已導致轉移到嵌套調用集中較早的函數中的setjmp
調用。
當你執行longjmp(jump_body, 1);
在func
,您使jump_ret
無效。
longjmp
不是雙向的 - 它展開堆棧,就好像setjmp
和longjmp
之間的任何函數調用從未發生過一樣。
您試圖將longjmp
從main()
堆棧返回到func()
。 這個沒有定義。 由於longjmp
本身就是一個函數,您很可能最終將longjmp
放入func
,返回地址是longjmp
調用本身,因此是一個無限循環。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.