精品欧美一区二区三区在线观看 _久久久久国色av免费观看性色_国产精品久久在线观看_亚洲第一综合网站_91精品又粗又猛又爽_小泽玛利亚一区二区免费_91亚洲精品国偷拍自产在线观看 _久久精品视频在线播放_美女精品久久久_欧美日韩国产成人在线

代碼安全性和健壯性:如何在if和assert中做選擇?

安全 應用安全
這篇文章分析了 C 語言中比較晦澀、模糊的一個概念,似乎有點虛無縹緲,但是的確又需要我們停下來仔細考慮一下。
  •  一、前言
  • 二、assert 斷言
  • 三、if VS assert
  • 四、總結

一、前言

我們在擼代碼的時候,經常需要對代碼的安全性進行檢查,例如:

1. 指針是否為空?

2. 被除數是否為 0?

3. 函數調用的返回結果是否有效?

4. 打開一個文件是否成功?

對這一類的邊界條件進行檢查的手段,一般都是使用 if 或者 assert 斷言,無論使用哪一個,都可以達到檢查的目的。那么是否就意味著:這兩者可以隨便使用,想起來哪個就用哪個?

這篇小短文我們就來掰扯掰扯:在不同的場景下,到底是應該用 if,還是應該使用 assert 斷言?

寫這篇文章的時候,我想起了孔乙己老先生的那個問題:茴香豆的“茴”字有幾種寫法?

似乎我們沒有必要來糾結應該怎么選擇,因為都能夠實現想要的功能。以前我也是這么想的,但是,現在我不這么認為。

成為技術大牛、拿到更好的offer,也許就在這些細微之間就分出了勝負。

二、assert 斷言

剛才,我問了下旁邊的一位工作 5 年多的嵌入式開發者:if 和 assert 如何選擇?他說:assert 是干什么的?!

看來,有必要先簡單說一下 assert 斷言。

assert() 的原型是:

  1. void assert(int expression); 

1. 如果宏的參數求值結果為非零值,則不做任何操作(no action);

2. 如果宏的參數是零值,就打印診斷消息,然后調用abort()。

例如下面的代碼:

  1. #include <assert.h> 
  2. int my_div(int a, int b) 
  3.     assert(0 != b); 
  4.     return a / b; 

1. 當 b 不為 0 時,assert 斷言什么都不做,程序往下執行;

2. 當 b 為 0 時,assert 斷言就打印錯誤信息,然后終止程序;

從功能上來說,assert(0 != b); 與下面的代碼等價:

  1. if (0 == b) 
  2.     fprintf(stderr, "b is zero..."); 
  3.     abort(); 

assert 是一個宏,不是一個函數

在 assert.h 頭文件中,有如下定義:

  1. #ifdef NDEBUG 
  2.     #define assert(condition) ((void)0) 
  3. #else 
  4.     #define assert(condition) /*implementation defined*/ 
  5. #endif 

既然是宏定義,說明是在預處理的時候進行宏替換。

從上面的定義中可以看到:

  1. 如果定義了宏 NDEBUG,那么 assert() 宏將不做什么動作,也就是相當于一條空語句:(void)0;,當在 release 階段編譯代碼的時候,都會在編譯選項中(Makefile)定義這個宏。
  2. 如果沒有定義宏 NDEBUG,那么 assert() 宏將會把一些檢查代碼進行替換,我們在開發階段執行 debug 模式編譯時,一般都會屏蔽掉這 NDEBUG 這個宏。

三、if VS assert

還是以一個代碼片段來描述問題,以場景化來討論比較容易理解。

  1. // brief: 把兩個短字符串拼接成一個字符串 
  2. char *my_concat(char *str1, char *str2) 
  3.     int len1 = strlen(str1); 
  4.     int len2 = strlen(str2); 
  5.     int len3 = len1 + len2; 
  6.     char *new_str = (char *)malloc(len3 + 1); 
  7.     memset(new_str, 0 len3 + 1); 
  8.     sprintf(new_str, "%s%s", str1, str2); 
  9.     return new_str; 

如果一個開發人員寫出上面的代碼,一定會被領導約談的!它存在下面這些問題:

  1. 沒有對輸入參數進行有效性檢查;
  2. 沒有對 malloc 的結果進行檢查;
  3. sprintf 的效率很低;
  4. ...

1. 使用 if 語句來檢查

  1. char *my_concat(char *str1, char *str2) 
  2.     if (!str1 || !str2)  // 參數錯誤 
  3.         return NULL
  4.          
  5.     int len1 = strlen(str1); 
  6.     int len2 = strlen(str2); 
  7.     int len3 = len1 + len2; 
  8.     char *new_str = (char *)malloc(len3 + 1); 
  9.      
  10.     if (!new_str)   // 申請堆空間失敗 
  11.         return NULL
  12.      
  13.     memset(new_str, 0 len3 + 1); 
  14.     sprintf(new_str, "%s%s", str1, str2); 
  15.     return new_str; 

2. 使用 assert 斷言來檢查

  1. char *my_concat(char *str1, char *str2) 
  2.     // 確保參數正確 
  3.     assert(NULL != str1); 
  4.     assert(NULL != str2); 
  5.      
  6.     int len1 = strlen(str1); 
  7.     int len2 = strlen(str2); 
  8.     int len3 = len1 + len2; 
  9.     char *new_str = (char *)malloc(len3 + 1); 
  10.      
  11.     // 確保申請堆空間成功 
  12.     assert(NULL != new_str); 
  13.      
  14.     memset(new_str, 0 len3 + 1); 
  15.     sprintf(new_str, "%s%s", str1, str2); 
  16.     return new_str; 

3. 你喜歡哪一個?

首先聲明一點:以上這 2 種檢查方式,在實際的代碼中都很常見,從功能上來說似乎也沒有什么影響。因此,沒有嚴格的錯與對之分,很多都是依賴于每個人的偏好習慣不同而已。

(1) assert 支持者

我作為 my_concat() 函數的實現者,目的是拼接字符串,那么傳入的參數必須是合法有效的,調用者需要負責這件事。如果傳入的參數無效,我會表示十分的驚訝!怎么辦:崩潰給你看!

(2)if 支持者

我寫的 my_concat() 函數十分的健壯,我就預料到調用者會亂搞,故意的傳入一些無效參數,來測試我的編碼水平。沒事,來吧,我可以處理任何情況!

這兩個派別的理由似乎都很充足!那究竟該如何選擇?難道真的的跟著感覺走嗎?

假設我們嚴格按照常規的流程去開發一個項目:

1. 在開發階段,編譯選項中不定義 NDEBUG 這個宏,那么 assert 就發揮作用;

2. 項目發布時,編譯選項中定義了 NDEBUG 換個宏,那么 assert 就相當于空語句;

也就是說,只有在 debug 開發階段,用 assert 斷言才能夠正確的檢查到參數無效。而到了 release 階段,assert 不起作用,如果調用者傳遞了無效參數,那么程序只有崩潰的命運了。

這說明什么問題?是代碼中存在 bug?還是代碼寫的不夠健壯?

從我個人的理解上看,這壓根就是單元測試沒有寫好,沒有測出來參數無效的這個 case!

4. assert 的本質

assert 就是為了驗證有效性,它最大作用就是:在開發階段,讓我們的程序盡可能地 crash。每一次的 crash,都意味著代碼中存在著 bug,需要我們去修正。

當我們寫下一個 assert 斷言的時候,就說明:斷言失敗的這種情況是不可以的,是不被允許的。必須保證斷言成功,程序才能繼續往下執行。

5. if-else 的本質

if-else 語句用于邏輯處理,它是為了處理各種可能出現的情況。就是說:每一個分支都是合理的,是允許出現的,我們都要對這些分支進行處理。

6. 我喜歡的版本

  1. char *my_concat(char *str1, char *str2) 
  2.     // 參數必須有效 
  3.     assert(NULL != str1); 
  4.     assert(NULL != str2); 
  5.      
  6.     int len1 = strlen(str1); 
  7.     int len2 = strlen(str2); 
  8.     int len3 = len1 + len2; 
  9.     char *new_str = (char *)malloc(len3 + 1); 
  10.      
  11.     // 申請堆空間失敗的情況,是可能的,是允許出現的情況。 
  12.     if (!new_str) 
  13.         return NULL
  14.      
  15.     memset(new_str, 0 len3 + 1); 
  16.     sprintf(new_str, "%s%s", str1, str2); 
  17.     return new_str; 

對于參數而言:我認為傳入的參數必須是有效的,如果出現了無效參數,說明代碼中存在 bug,不允許出現這樣的情況,必須解決掉。

對于資源分配結果(malloc 函數)而言:我認為資源分配失敗是合理的,是有可能的,是允許出現的,而且我也對這個情況進行了處理。

當然了,并不是說對參數檢查就要使用 assert,主要是根據不同的場景、語義來判斷。例如下面的這個例子:

  1. int g_state; 
  2. void get_error_str(bool flag) 
  3.     if (TRUE == flag) 
  4.     { 
  5.         g_state = 1; 
  6.         assert(1 == g_state); // 確保賦值成功 
  7.     } 
  8.     else 
  9.     { 
  10.         g_state = 0; 
  11.         assert(0 == g_state); // 確保賦值成功 
  12.     } 

flag 參數代表不同的分支情況,而賦值給 g_state 之后,必須保證賦值結果的正確性,因此使用 assert 斷言。

四、總結

這篇文章分析了 C 語言中比較晦澀、模糊的一個概念,似乎有點虛無縹緲,但是的確又需要我們停下來仔細考慮一下。

如果有些場景,實在拿捏不好,我就會問自己一個問題:

這種情況是否被允許出現?

不允許:就用 assert 斷言,在開發階段就盡量找出所有的錯誤情況;

允許:就用 if-else,說明這是一個合理的邏輯,需要進行下一步處理。

本文轉載自微信公眾號「IOT物聯網小鎮」,可以通過以下二維碼關注。轉載本文請聯系IOT物聯網小鎮公眾號。

 

責任編輯:武曉燕 來源: IOT物聯網小鎮
相關推薦

2023-11-17 11:55:54

Pythonretrying庫

2015-09-25 10:17:01

AWS合規性安全風險

2017-02-05 15:10:55

Option函數式編程代碼

2021-07-30 11:21:39

物聯網網絡安全IoT

2024-01-08 09:38:51

Java數據

2025-02-13 00:28:26

2010-12-07 09:51:43

Linux安全性netfilteriptables

2009-11-06 09:59:55

2023-06-01 15:17:17

2023-11-17 12:29:57

API安全性零信任

2015-06-15 10:48:25

2019-01-17 10:58:37

2023-09-27 16:08:37

2023-12-27 14:50:10

2010-06-03 15:23:48

2015-05-11 10:42:17

混合云性能混合云安全SLA

2016-03-14 12:36:29

2013-09-18 09:13:16

BYOD安全BYOD自帶設備辦公

2022-07-04 09:30:59

Kubernetes云安全

2009-07-01 15:25:16

Servlet和JSP
點贊
收藏

51CTO技術棧公眾號

在线免费高清一区二区三区| 91精品麻豆| 久久久www免费人成精品| 国产精国产精品| 尤物在线免费视频| 国产精品丝袜在线播放| 欧美色视频一区| 国产欧美日韩小视频| 国产日产精品久久久久久婷婷| 久久精品99久久久| 97久久精品国产| 国产又粗又猛又爽又黄的视频四季 | 国产成人啪精品午夜在线观看| 狠狠做六月爱婷婷综合aⅴ| 日韩三级.com| 浓精h攵女乱爱av| 国产精品yjizz视频网| 中文字幕一区二区在线播放| 黄色一区三区| 亚洲av无码一区二区乱子伦| 蜜臀a∨国产成人精品| 91国产精品视频在线| 欧美一级淫片007| 国产日韩av在线播放| 精品少妇久久久| 欧美r级电影| 亚洲毛片在线看| 四虎国产精品永久免费观看视频| 色8久久影院午夜场| 婷婷开心久久网| 日韩一级免费看| 国产福利视频在线| 国产精品色呦呦| 久久综合九色99| 欧美熟妇交换久久久久久分类| 久久99精品一区二区三区| 欧洲精品久久久| 美日韩一二三区| 国产视频一区欧美| 韩国精品久久久999| 国产一级aa大片毛片| 影音先锋日韩在线| 精品自在线视频| 欧美成人精品欧美一级| 亚洲电影影音先锋| 美女撒尿一区二区三区| 日本在线一级片| 永久亚洲成a人片777777| 久久夜色撩人精品| 欧美第一页在线观看| 亚洲九九视频| 欧美精品在线免费| 国产亚洲欧美久久久久 | 男人天堂新网址| 影音先锋男人在线资源| 亚洲宅男天堂在线观看无病毒| 在线视频亚洲自拍| 粗大黑人巨茎大战欧美成人| 亚洲欧美色综合| 中文精品无码中文字幕无码专区 | 日韩精品欧美| 日韩有码在线播放| 极品魔鬼身材女神啪啪精品| 欧美激情综合色综合啪啪| 九九视频直播综合网| 免费观看一级视频| 久久精品在线| 国产精品自产拍高潮在线观看| 中文字字幕在线观看| 韩国理伦片一区二区三区在线播放| 国产综合在线观看视频| 99久久精品免费看国产交换| 成人免费视频国产在线观看| 裸模一区二区三区免费| 69xxxx欧美| 一区二区三区在线视频观看58 | 日av在线不卡| 91亚洲永久免费精品| 东京干手机福利视频| 97se亚洲国产综合在线| 视频一区视频二区视频| 在线三级中文| 日本韩国一区二区| 久久久久久久高清| 性欧美xxxx免费岛国不卡电影| 在线观看日韩欧美| 国产亚洲第一页| 欧美一区=区| 成人在线激情视频| 香蕉视频911| 综合亚洲深深色噜噜狠狠网站| 拔插拔插海外华人免费| 中文.日本.精品| 精品免费国产一区二区三区四区| 37p粉嫩大胆色噜噜噜| 亚洲精品888| 国产91久久婷婷一区二区| va视频在线观看| 久久精品视频网| 久久久久久久9| 国产美女久久| 亚洲精品mp4| 99久久婷婷国产综合| 每日更新成人在线视频| 国产成人精品一区二区三区福利 | 日本亚洲不卡| 精品国产一区av| 青青草免费观看视频| 国产精品一区二区久久不卡 | 亚洲午夜激情网页| 中文字幕av不卡在线| 欧美性生活一级片| 久久国产精品网站| 亚洲自拍偷拍另类| 久久久久久久久久久久久久久99| 免费一级淫片aaa片毛片a级| 欧美午夜三级| 亚洲色图美腿丝袜| 日本在线播放视频| 成人高清伦理免费影院在线观看| 国产又黄又爽免费视频| 亚洲插插视频| 日韩精品黄色网| 国产对白videos麻豆高潮| 国产一区二区三区在线观看精品| 亚欧洲精品在线视频免费观看| 国产无遮挡裸体视频在线观看| 日韩久久久精品| 岛国毛片在线观看| 国模少妇一区二区三区| 亚洲精品一区二区三区av| 新片速递亚洲合集欧美合集| 亚洲剧情一区二区| 91视频免费网址| 久久影院午夜片一区| 9l视频自拍9l视频自拍| 欧美亚洲黄色| 色av中文字幕一区| 伊人网免费视频| 国产亚洲成av人在线观看导航| 国产二区视频在线播放| 欧洲亚洲视频| 91成人精品网站| 天堂中文在线视频| 婷婷综合五月天| 波多野结衣先锋影音| 国产精品久久久久久模特| 精品国产综合久久| 免费在线小视频| 亚洲人成在线一二| 国产天堂第一区| ●精品国产综合乱码久久久久| 欧美大片久久久| 亚洲欧美文学| 国内精品久久久久久久果冻传媒| 爱草tv视频在线观看992| 亚洲精品成人免费| 欧美日韩一级黄色片| 国产蜜臀av在线一区二区三区| 国产精品视频分类| 97精品国产| 国产精成人品localhost| 国产剧情av在线播放| 亚洲精品美女久久久| 免费无码国产精品| 自拍偷自拍亚洲精品播放| 扒开伸进免费视频| 新67194成人永久网站| 日韩伦理一区二区三区av在线| 欧美aaa级| 欧美大片网站在线观看| 三级视频在线看| 在线观看视频一区二区欧美日韩| 亚洲第一综合网| 国产精品一卡二卡| aa在线免费观看| 日韩精品免费| 精品国产一区二区三区日日嗨| 亚洲精品555| 欧美激情国产日韩精品一区18| 四虎影视精品成人| 欧美日韩一级二级| 久久精品女人毛片国产| 国产欧美日本一区视频| 师生出轨h灌满了1v1| 久久国产欧美| 免费观看中文字幕| 精品中文字幕一区二区三区av| 成人亲热视频网站| 日韩伦理在线一区| 超碰日本道色综合久久综合| 欧美女v视频| 日韩欧美另类在线| 久久人人爽人人爽人人片av免费| 亚洲男女毛片无遮挡| 色婷婷av777| 国产一区二区三区久久悠悠色av| 人妻精品无码一区二区三区| 欧美日韩午夜| 一区二区视频在线播放| 欧美爱爱网站| 91福利视频导航| 欧美风情在线视频| 97欧美精品一区二区三区| 成人区精品一区二区不卡| 亚洲美女性视频| 午夜精品久久久久久久第一页按摩 | 大陆av在线播放| 99视频精品视频高清免费| 久久精品日产第一区二区三区| 激情不卡一区二区三区视频在线| 国产91色在线|免| 678在线观看视频| 久久在线视频在线| 欧美极品另类| 国产一区二区久久精品| 午夜激情在线视频| 亚洲福利视频在线| 国产浮力第一页| 欧美巨大另类极品videosbest | 国产精品第13页| 乐播av一区二区三区| 99精品视频一区二区三区| 五月天视频在线观看| 日韩高清一级片| 无码人妻h动漫| 99精品国产在热久久| 日本wwwcom| 欧美日韩国产成人精品| 熟女视频一区二区三区| 婷婷激情图片久久| 资源网第一页久久久| 日本一区二区三区视频| 神马影院我不卡午夜| av资源久久| 相泽南亚洲一区二区在线播放 | 精品视频在线观看一区二区| 婷婷色综合网| 99热都是精品| 欧美 日韩 国产一区二区在线视频| 中国一级黄色录像| 一精品久久久| 国产激情在线看| 国产专区一区| 美女扒开大腿让男人桶| 999在线观看精品免费不卡网站| 久久久久久久香蕉| 亚洲婷婷免费| 日韩人妻精品无码一区二区三区| 免费国产自线拍一欧美视频| 国产v亚洲v天堂无码久久久 | 欧美日韩第一区| 99在线免费视频观看| 99精品视频免费观看| 激情综合在线观看| 日本午夜一本久久久综合| 91最新在线观看| 九九久久精品视频| jjzz黄色片| av福利精品导航| 最近中文字幕免费视频| 国产精品久久久久久亚洲毛片| 成年人二级毛片| 亚洲一区二区三区国产| 在线观看日韩中文字幕| 欧美少妇一区二区| av老司机久久| 亚洲国内高清视频| caoporn国产精品免费视频| x99av成人免费| 黑人玩欧美人三根一起进| 欧美一级视频免费在线观看| 日本精品网站| 国产91亚洲精品一区二区三区| 日韩精品免费一区二区三区竹菊 | 欧美日韩激情一区| 精品人妻一区二区三区换脸明星| 亚洲精品www久久久久久广东| 成人av一区| 欧美—级高清免费播放| 欧美大片免费高清观看| 91免费国产视频| 妖精视频一区二区三区| 日本黄色a视频| 国产亚洲成人一区| 中文av一区二区三区| 国产凹凸在线观看一区二区| 中文字幕网站在线观看| 亚洲主播在线播放| 最好看的日本字幕mv视频大全| 日韩欧美一二区| www.亚洲视频| 国内成人精品视频| 国产精品**亚洲精品| 欧美大香线蕉线伊人久久国产精品 | 亚洲熟妇无码av在线播放| 七七婷婷婷婷精品国产| 久久久男人的天堂| 国产精品午夜久久| 四虎精品永久在线| 日韩视频在线永久播放| 成人在线观看一区| 91国产高清在线| 日韩欧美一级| 国产又爽又黄ai换脸| 久久看片网站| 亚洲欧美日韩色| 亚洲人妖av一区二区| 久久久久久无码精品大片| 精品国产乱码久久久久久老虎 | 福利精品视频在线| www.国产欧美| 精品国内亚洲在观看18黄| 中文一区一区三区高中清不卡免费| 亚洲a在线观看| 日韩av在线播放网址| 人妻无码视频一区二区三区| av在线一区二区三区| 欧美日韩激情在线观看| 欧美片网站yy| 77导航福利在线| 国产精品久久久久久久久影视 | 最近看过的日韩成人| 日韩精品1区2区3区| 能免费看av的网站| 亚洲成人久久影院| www.五月婷| 欧美巨猛xxxx猛交黑人97人| 国产日韩在线观看视频| 亚洲三区在线观看| 美女视频第一区二区三区免费观看网站| 一本色道综合久久欧美日韩精品 | 国产精品久久久网站| 久久视频免费在线| 国产精品一区二区在线观看不卡 | 日韩欧美国产综合在线一区二区三区 | 99天天综合性| 日韩精品乱码久久久久久| 亚洲第一精品夜夜躁人人爽| 欧美女同一区| 国产一区二区在线网站| 国产欧美综合一区二区三区| 少妇饥渴放荡91麻豆| 偷窥少妇高潮呻吟av久久免费 | 久久久久北条麻妃免费看| 欧美亚洲人成在线| 黄色免费高清视频| 国产精品一区二区91| 国产在线欧美在线| 亚洲精品白浆高清久久久久久| 亚洲插插视频| 日本一区二区三区免费看| 奇米精品一区二区三区在线观看一| 久久久久亚洲AV成人无在| 欧美日韩亚洲综合| 亚洲精品天堂| 国产一区二区三区四区五区加勒比| 亚洲一区二区动漫| 天天躁日日躁aaaa视频| 欧美视频一区二区在线观看| 欧洲不卡av| 亚洲xxx视频| 亚洲在线一区| 女性裸体视频网站| 精品国精品国产| 中文字幕在线官网| 性欧美大战久久久久久久免费观看| 国产综合成人久久大片91| 九九久久免费视频| 精品一区精品二区| 日韩一区二区三免费高清在线观看| 国产日韩第一页| 99re这里只有精品首页| 中文字幕天堂在线| 九九精品在线观看| 亚洲专区视频| 亚洲成人av免费观看| 欧美日韩精品在线观看| 在线观看黄色av| 国产伦精品一区二区三区视频免费| 亚洲欧美卡通另类91av| 国产精品suv一区二区88| 欧美精品一区二区三区视频| av在线一区不卡| 国产精品久久久久久久久电影网| 久久久久国产精品麻豆| 午夜精品久久久久久久99| 国产成人鲁鲁免费视频a| 欧美一区二区三区另类| 中文字幕被公侵犯的漂亮人妻| 日韩久久精品一区| 国产亚洲精品精品国产亚洲综合| 国产精品入口芒果| 国产精品美女久久福利网站| 人妻偷人精品一区二区三区| 国产精品美女在线观看| 亚洲免费播放| 性欧美videos| 色噜噜狠狠狠综合曰曰曰88av| 日韩欧美黄色|