在c語言中,當巢狀函式呼叫出錯時,可以採用非區域性跳轉函式setjmp和longjmp,利用這兩個函式可以把程式控制流進行有效轉移,這兩個函式相結合可以在棧上跳過若干呼叫幀,返回到當前函式呼叫路徑上的某乙個函式中。
[cpp]view plain
copy
/* setjmp 和 longjmp 函式 */
/** 函式功能:當某個巢狀函式出錯時,可實現程式控制流跳轉;
* 函式原型:
* #include
* int setjmp(jmp_buf env);//若直接呼叫則返回0,若從longjmp呼叫則返回非0值;
** void longjmp(jmp_buf env, int val);
* 說明:
* 引數env是某種形式的陣列,存放在呼叫longjmp時能恢復棧狀態的所有資訊,一般定義為全域性變數;
* val設定setjmp的返回值;*/
測試程式
[cpp]view plain
copy
#include
#include "apue.h"
static
jmp_buf
env;
static
intglobval;
//全域性變數
static
void
fun1(
int,
int,
int,
int);
static
void
fun2(
void
);
intmain(
void
)
globval = 10; autoval = 11;
registerval = 12; volatileval = 13;
staticval = 14;
fun1(autoval,registerval,volatileval,staticval);
exit(0);
} static
void
fun1(
inti,
intj,
intk,
intl)
static
void
fun2(
void
)
輸出結果:
沒有優化編譯的結果:
[cpp]view plain
copy
in funi():
globval= 10, autoval= 11, registerval= 12,volatileval= 13, staticval= 14
after longjmp:
globval= 10, autoval= 11, registerval= 3,volatileval= 13, staticval= 14
longjmp error
優化編譯的結果:
[cpp]view plain
copy
in funi():
globval= 10, autoval= 11, registerval= 12,volatileval= 13, staticval= 14
after longjmp:
globval= 10, autoval= 2, registerval= 3,volatileval= 13, staticval= 14
longjmp error
測序講解:
1、在main函式中,第一次直接呼叫setjmp時返回值是0,所以不執行main函式的列印部分,直接呼叫fun1函式;
2、在fun1函式中,首先列印兩條語句,然後呼叫fun2函式。
[cpp]view plain
copy
printf(
"in funi():\n"
);
printf("globval= %d, autoval= %d, registerval= %d,"
"volatileval= %d, staticval= %d\n"
, i,j,k,l);
3、在fun2函式中,呼叫longjmp函式,相當於在這裡程式出錯,返回到main函式的setjmp處,這次是main函式中的setjmp返回值是val=1,則執行以下的列印資訊,然後exit退出main函式:
[cpp]view plain
copy
printf(
"after longjmp:\n"
);
printf("globval= %d, autoval= %d, registerval= %d,"
"volatileval= %d, staticval= %d\n"
, globval,autoval,registerval,volatileval,staticval);
printf("longjmp error\n"
);
關於全域性變數、自動變數、暫存器變數、易失變數、靜態變數在setjmp和longjmp函式中的變化是有區別的,存放在儲存器的變數將和longjmp時的值一樣,存放在cpu和浮點暫存器的變數則會恢復為呼叫setjmp時的值。自動變數、暫存器變數存放在暫存器中,所以其變數值恢復到呼叫setjmp時的值,全域性變數、易失變數、靜態變數存放在儲存器中,所以變數將和longjmp時的值一樣。
《unix高階環境程式設計》程序環境 程序終止
當核心執行c程式時 使用乙個exec函式執行 在呼叫mian函式前先呼叫乙個特殊的啟動例程。可執行程式檔案將此啟動例程指定為程式的起始位址。下面是c程式啟動和終止的流程,由圖中可以知道,程序的終止根據不同的函式呼叫是不一樣的,其中 exit和 exit函式是終止程序直接進入核心,exit函式則先執行...
《unix高階環境程式設計》程序環境 環境變數
環境字串一般表示如下 cpp view plain copy name value 環境變數名,環境變數值 以下根據對環境變數不同的操作得到不同的結果,包括獲取環境變數當前值,新增環境變數,修改環境變數和刪除環境變數 相對應的函式分別為getenv putenv setenv和unsetenv函式,...
unix環境高階程式設計 守護程序
守護程序 daemon 是生存期長的一種程序,常常在系統引導裝入時啟動,僅在系統關閉時終止,因為它們沒有控制終端,unix有很多守護程序,它們執行日常事務活動。守護程序的特徵 執行指令 ps zxj a顯示其他使用者擁有的程序狀態,x顯示沒有終端控制的程序狀態,j顯示與作業有關的資訊 會話id 程序...