传入参数0调用longjmp时为何setjmp的if判断分支会触发?
原因说明
这是C语言标准对setjmp/longjmp非本地跳转机制的明确行为规定,出现和直觉预期不符的结果,核心是不了解该接口的特殊返回值规则:
- 第一次直接调用
setjmp保存执行上下文时,返回值固定为0,示例代码中首次走到if判断时条件不成立,会正常向下执行Com_Error调用。 - 当后续通过
longjmp跳回setjmp保存的执行点时,setjmp会产生第二次返回,返回值遵循强制规则:- 若传入
longjmp的第二个参数不为0,setjmp直接返回该参数值 - 若传入
longjmp的第二个参数为0,setjmp会强制返回1,绝不会返回0
- 若传入
设计这个规则的目的是彻底消除歧义:只要setjmp返回0,就一定是首次调用的初始返回;只要返回非0,就一定是从longjmp跳转回来的返回,从根源上避免两种场景混淆导致的逻辑死循环、错误分支问题。
示例代码的实际执行流程完全符合标准定义:
- 首次执行
setjmp(abortframe),返回0,if条件不成立,继续向下运行 - 调用
Com_Error(0),内部执行longjmp(abortframe, 0)触发非本地跳转,回到之前setjmp的执行位置 - 此时
setjmp按照规则强制返回1,if判断条件成立,进入分支打印abortframe!。
内容的提问来源于stack exchange,提问作者darro911
相关产品推荐
相关产品推荐

