C語言學習趣事_20_Assert_Setjmp

來源:互聯網
上載者:User

  最近看C庫,簡單的學習了一下assert和setjmp庫的功能,貼點心得。

/*
本程式測試庫函數,用來學習、理解庫
*/

#include <stdio.h>
/*
測試:assert宏 與 NDEBUG的關係
Tip:
經過各種測試,為了取消 assert 宏,必須在它之前定義NEDBUG;
這裡也說明一個問題,宏的定義和引用是有先後順序的
如果
#undef NDEBUG
#define NDEBUG

#include <assert.h> 之後定義 NDEBUG 宏,那麼就不能取消assert宏

這裡有一個比較特殊的效能,無論某個宏是否被定義,都可以用#undef 來取消它。
*/
#undef NDEBUG
#define NDEBUG
#include <assert.h>
#include <setjmp.h>
#include <stdio.h>
#include <stdlib.h>



/*
測試setjmp標準標頭檔

<setjmp.h>標頭檔功能:
用來實現非模組化函數編程。

資料類型:jmp_buf
#define _JBLEN 16
#define _JBTYPE int
typedef _JBTYPE jmp_buf[_JBLEN];
這裡可以看出:
jmp_buf: 為一個 int [16] 類型
宏 setjmp(jmp_buf env)
setjmp(jmp_buf env) 是一個宏定義,用來代替set_jmp 函數;
這個宏用來設定 env 變數, env變數儲存設定位置行的程式地址;
設定時返回 0;
當執行longjmp函數的時候,就從set_jmp設定的位置開始執行,並且
再次從設定位置執行的時候 set_jmp 宏返回longjup指定的值。
函數 longjmp(jmp_buf env, int val)
函數導致程式執行結構跳轉到 setjmp 設定的 env 地址處執行,並且
設定再次執行 env 地址處的函數時 setjmp 宏的傳回值。
Tip:
注意利用這個特性會破壞模組化的編程結構,這個用法主要用於處理
低級操作時的嚴重錯誤。

*/
static jmp_buf buf;
void test_jmp_fun(void)
{
/*
如果去掉static的話,則這個函數列印隨即的值
如果保留static的話,則列印 5 。
並且會在輸出 :
puts("Set_jmp call:\n");後輸出5
*/
volatile static int i_test;

i_test=3;

if( setjmp(buf) == 1 )
{
printf("%d\n",i_test);
exit(0);
}

i_test=5;
}


int main(int argc,char *argv[])
{
int i_assert;

i_assert=0;


/*
測試 assert 宏
用法:
#include <assert.h>
void assert(int expression)
功能:
assert宏測試 expression 的值,如果expression的值 =0;則
異常中斷程式,並且輸出一些資訊;包括 運算式的文本、源檔案
的名字(包括路徑)、和出錯行在原文本中的行數。
後兩者分別是:
_FILE_ 宏

_LINE_ 宏
的值。
當執行完前面的操作後,就退出程式的執行。
*/
assert(i_assert);

/*
測試編譯器預定義的宏:
__FILE__ : 不需要包含標頭檔,這個預定義的宏,由編譯器負責解釋,
它表示源檔案的名字,包括路徑。
__LINE__: 不需要包含標頭檔,這個預定義的宏,由編譯器負責解釋,
由它表示這個宏所在的行數。
*/
puts(__FILE__);
printf("This line is %d th line.\n",__LINE__);


printf("The max value is %d\n",max(3,5));


test_jmp_fun();
puts("Set_jmp call:");
longjmp(buf,1);


return 0;
}

下面是引用的另外一個檔案,下面的注釋部分是VS 2008的編譯資訊,可以發現串連之前,max為未定義的標識符。

/*
1>------ Rebuild All started: Project: LibTest, Configuration: Debug Win32 ------
1>Deleting intermediate and output files for project 'LibTest', configuration 'Debug|Win32'
1>Compiling...
1>main.c
1>g:\03_c_code_exp\libtest\libtest\main.c(75) : warning C4013: 'max' undefined; assuming extern returning int
1>test.c
1>Generating Code...
1>Compiling manifest to resources...
1>Microsoft (R) Windows (R) Resource Compiler Version 6.0.5724.0
1>Copyright (C) Microsoft Corporation. All rights reserved.
1>Linking...
1>LINK : G:\03_C_Code_Exp\LibTest\Debug\LibTest.exe not found or not built by the last incremental link; performing full link
1>Embedding manifest...
1>Microsoft (R) Windows (R) Resource Compiler Version 6.0.5724.0
1>Copyright (C) Microsoft Corporation. All rights reserved.
1>Build log was saved at "file://g:\03_C_Code_Exp\LibTest\LibTest\Debug\BuildLog.htm"
1>LibTest - 0 error(s), 1 warning(s)
========== Rebuild All: 1 succeeded, 0 failed, 0 skipped ==========
*/
int max(int x,int y)
{
return x>y?x:y;
}
相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.