非本地跳转

首先介绍下与非本地跳转的对应的本地跳转,本地跳转指的是类似于goto语句的一系列应用,当设置了标志之后,可以跳到所在函数内部的标号上。然而,本地跳转不能将控制权转移到所在程序的任意地点,不能跨越函数,因此也就有了非本地跳转

 1.非本地跳转是C语言提供的一种用户级的异常控制流的形式,它将控制直接从一个函数转移到另一个当前正在执行的函数,而不需要经过正常的调用-返回序列。

非本地跳转是通过setjmp和longjmp函数提供的。

 我们来看看函数:

1 #include <setjmp.h>
2 //setjmp函数在env缓冲区中保存当前调用环境,以供后面的longjmp使用
3 int setjmp(jmp_buf env);
4 int sigsetjmp(sigjmp_buf env,int savesigs);
5 //sigsetjmp函数和siglongjmp函数是setjmp和longjmp的可以被信号处理程序使用的版本
6 //longjmp函数从env缓冲区中恢复调用环境,然后触发一个最近一次初始化env的setjmp调用的返回,然后setjmp返回,并带有非零的返回值retval
7 void longjmp(jmp_buf env,int retval);
8 void siglongjmp(sigjmp_buf env,int retval);
 返回值:若直接调用则返回0,若从siglongjmp调用返回则返回非0值

   要注意一点,setjmp的返回值不能被赋值给变量。但是可以用在switch语句或者条件语句的测试中

   setjmp函数只调用一次,但是返回多次,一次是当第一次调用setjmp,而调用环境保存在缓冲区env中时,一次是为每个相应的longjmp调用。

   longjmp函数被调用一次但从不返回。

2.应用

  2.1非本地跳转允许从一个深层嵌套的函数调用中立即返回,通常由检测到某个错误引起的。

  示例代码:

  

 1 #include "csapp.h"
 2
 3 jmp_buf buf;
 4
 5 int error1 = 0;
 6 int error2 = 1;
 7
 8 void foo(void), bar(void);
 9
10 int main()
11 {
12     int rc;
13
14     rc = setjmp(buf);
15     if (rc == 0)
16     foo();
17     else if (rc == 1)
18     printf("Detected an error1 condition in foo\n");
19     else if (rc == 2)
20     printf("Detected an error2 condition in foo\n");
21     else
22     printf("Unknown error condition in foo\n");
23     exit(0);
24 }
25
26 /* deeply nested function foo */
27 void foo(void)
28 {
29     if (error1)
30     longjmp(buf, 1);
31     bar();
32 }
33
34 void bar(void)
35 {
36     if (error2)
37     longjmp(buf, 2);
38 }

 2.2使信号处理程序分支到一个特殊的代码位置,而不是返回到被信号到达中断了的指令位置

  示例代码:

  这个代码挺有意思

 1 #include "csapp.h"
 2
 3 sigjmp_buf buf;
 4
 5 void handler(int sig)
 6 {
 7     siglongjmp(buf, 1);
 8 }
 9
10 int main()
11 {
12     Signal(SIGINT, handler);
13
14     if (!sigsetjmp(buf, 1))
15 /*The initial call to the sigsetjmp function saves the stack and signal context when the program first starts.*/
16     printf("starting\n");
17     else
18     printf("restarting\n");
19
20     while(1) {
21     Sleep(1);
22     printf("processing...\n");
23     }
24     exit(0);
25 }

原文地址:https://www.cnblogs.com/blzm742624643/p/9785146.html

时间: 2024-11-14 12:33:49

非本地跳转的相关文章

非本地跳转之setjmp与longjmp

非本地跳转(unlocal jump)是与本地跳转相对应的一个概念. 本地跳转主要指的是类似于goto语句的一系列应用,当设置了标志之后,可以跳到所在函数内部的标号上.然而,本地跳转不能将控制权转移到所在程序的任意地点,不能跨越函数,因此也就有了非本地跳转. C语言里面提供了setjmp和longjmp函数来进行跨越函数之间的控制权的跳转,从而称之为非本地跳转. #include <setjmp.h> int setjmp(jmp_buf env); 该函数主要用来保存当前执行状态,作为后续跳

第5章 进程环境(5)_非局部跳转

6. 非局部跳转 (1)setjmp和longjmp语句 头文件 #include<setjmp.h> 函数 int* setjmp(jum_buf env); 返回值 直接调用返回0,若从longjmp调用返回则返回非0值 功能 设置非局部跳转的跳转点   函数 void longjmp(jmp_buf env, int val); 功能 进行非局部转转,val为返回值 参数 env:一个特殊类型jmp_buf.这一数据类型是某种形式的数组,其中存放在调用longjmp时能用来恢复栈状态的信

解决eclipse中自带的maven搜索不到非本地第三方包问题

最近使用eclipse中的maven插件时发现,在pom.xml文件中添加第三方包时,查询不到非本地的jar包,感到格外不方便,也感到非常困惑.我记得在早期的eclipse版本中是自己安装maven插件,不存在该问题,于是就花费了半个小时时间来研究了下,结果发现,eclipse自带的插件,默认不会将第三方包索引下载到本地,所以就搜索不到了,按如下方法就可以下载并使用了 1. 打开windows -> preferences -> maven,勾选如图所示 2.  打开 windows ->

QT窗口置顶/真透明/背景模糊/非矩形/跳过任务栏分页器/无边框/无焦点点击/焦点穿透

qt 窗口置顶/真透明/背景模糊/非矩形/跳过任务栏分页器/无边框/无焦点点击/焦点穿透 窗口置顶qt 里是 setWindowFlags(Qt::WindowStaysOnTopHint)kde 里是 KWindowSystem::setState(winId(), NET::KeepAbove)这样的置顶窗口不会处于全屏窗口的上方,如果需要真正的置顶,setWindowFlags(Qt::X11BypassWindowManagerHint) 可无视这个规则,但这样不会出现任务栏等,kimt

asp.net mvc输出自定义404等错误页面,非302跳转。

朋友问到一个问题,如何输出自定义错误页面,不使用302跳转.当前页面地址不能改变. 还要执行一些代码等,生成一些错误信息,方便用户提交反馈. 500错误,mvc框架已经有现成解决方法: filters.Add(new HandleErrorAttribute()); 404错误目前想到的解决方法: 先上代码 Global.asax: 1 protected void Application_Error(object sender, EventArgs e) 2 { 3 var ex = Serv

【转】浅析C语言的非局部跳转:setjmp和longjmp

转自 http://www.cnblogs.com/lienhua34/archive/2012/04/22/2464859.html C语言中有一个goto语句,其可以结合标号实现函数内部的任意跳转(通常情况下,很多人都建议不要使用goto语句,因为采用goto语句后,代码维护工作量加大).另外,C语言标准中还提供一种非局部跳转“no-local goto",其通过标准库<setjmp.h>中的两个标准函数setjmp和longjmp来实现. C标准库<setjmp.h>

使用expdp(非本地)远程导出数据

背景: 前段时间,需要从异地一个测试数据库中将测试数据(一张表)导入本地库,表数据量大约500万,字段160多个,开始用了exp/imp方式,速度奇慢,不能忍,于是转而使用expdp/impdp方式. expdp/impd介绍: 从10g开始,除了传统的exp/imp导入导出工具外,Oracle提供了expdp/impdp的数据泵导入导出工具. 从官方文档上看(http://docs.oracle.com/cd/E11882_01/server.112/e22490/dp_overview.ht

asp.net mvc输出自定义404等错误页面,非302跳转

朋友问到一个问题,如何输出自定义错误页面,不使用302跳转.当前页面地址不能改变. 还要执行一些代码等,生成一些错误信息,方便用户提交反馈. 500错误,mvc框架已经有现成解决方法: filters.Add(new HandleErrorAttribute()); 404错误目前想到的解决方法: 先上代码 Global.asax: 1 protected void Application_Error(object sender, EventArgs e) 2 { 3 var ex = Serv

Yii 访问 Gii(脚手架)时出现 403 错误(非本地访问)

今天配置好了服务器(win server + upupw(nginx+mysql))内的 Yii framework 2,测试项目的Gii设置,结果出现#403错误页面: Error 403 You are not allowed to access this page. 1.调整了文件的读写权限,通过域名访问(外网访问.本地访问),仍然403报错.2. 然后在服务器本地访问(http://localhost/backend/web/index.php?r=gii) 仍报错403.3. 按照网上