You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C语言中setjmp与longjmp的行为理解及代码执行流程疑问

setjmp/longjmp程序执行逻辑解释

核心前提

C标准明确规定:如果调用longjmp时,此前调用setjmp保存上下文的函数已经执行完毕返回,那么该操作的行为是未定义行为,程序的表现完全取决于编译环境、运行平台,没有统一的标准结果,你看到的输出只是当前环境下的特定表现。

你当前环境下的执行流程拆解

我们按照你给出的输出反推实际执行过程:

  1. main函数先执行第17行代码,输出hello main
  2. 执行第18行调用hello()函数,进入函数后执行第8行的setjmp(env):
    • 首次调用setjmp会将当前的栈指针(sp)、帧指针(fp)、程序计数器(pc)等值保存到env全局变量中,同时返回0
    • 因为ret=0,不进入if分支,直接执行第13行输出hello called
    • hello函数执行完毕,返回main函数
  3. 回到main函数执行第19行,输出after hello call,接着执行第20行的longjmp(env, 1)
  4. longjmp恢复env中保存的寄存器上下文:
    • 程序跳回hello函数中第8行setjmp的返回位置,这次setjmp返回值为传入的1,即ret=1
    • 进入if分支,执行第11行输出error
    • 继续执行第13行输出hello called
  5. 此时hello函数要执行返回逻辑,但因为hello此前已经返回过一次,栈结构已经被破坏,你预期的“返回main第19行”的情况没有发生,在你当前的运行环境中,栈上保存的返回地址已经被篡改,程序直接退出,因此没有出现无限循环。

认知误区说明

你以为longjmp跳转后hello执行完会正常回到main第19行的前提是:setjmp所在的hello函数栈帧是完整合法的。只有在hello函数未返回时,在它的下级调用函数中执行longjmp跳转,才能保证栈帧合法,返回逻辑符合预期。你代码中的使用方式本身就不符合标准要求,因此不会按照你的预期执行。


内容的提问来源于stack exchange,提问作者InsaneCoder

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.05 23:09:01