這里只針對單核CPU,linux內核和其他一些開源的代碼中,經常會遇到這樣的代碼:
do{ ... }while(0)
這樣的代碼一看就不是一個循環,do..while表面上在這里一點意義都沒有,那么為什么要這么用呢?
實際上,do{...}while(0)的作用遠大于美化你的代碼。查了些資料,總結起來這樣寫主要有以下幾點好處:
1、輔助定義復雜的宏,避免引用的時候出錯: 舉例來說,假設你需要定義這樣一個宏:
#define DOSOMETHING() foo1(); foo2();這個宏的本意是,當調用DOSOMETHING()時,函數foo1()和foo2()都會被調用。但是如果你在調用的時候這么寫:
if(a > 0) DOSOMETHING();因為宏在預處理的時候會直接被展開,你實際上寫的代碼是這個樣子的:
if(a > 0) foo1(); foo2();這就出現了問題,因為無論a是否大于0,foo2()都會被執行,導致程序出錯。
那么僅僅使用{}將foo1()和foo2()包起來行么?
我們在寫代碼的時候都習慣在語句右面加上分號,如果在宏中使用{},代碼里就相當于這樣寫了:“ { ... } ; ”,展開后就是這個樣子 :
if(a > 0) { foo1(); foo2(); };這樣甚至不會編譯通過。所以,很多人才采用了do{...}while(0);
#define DOSOMETHING() do{ foo1(); foo2(); }while(0) ... if(a > 0) DOSOMETHING(); ...這樣,宏被展開后,才會保留初始的語義。GCC提供了Statement-Expressions用以替代do{...}while(0); 所以你也可以這樣定義宏:
#define DOSOMETHING() ({ foo1(); foo2(); })2、避免使用goto對程序流進行統一的控制: 有些函數中,在函數return之前我們經常會進行一些收尾的工作,比如free掉一塊函數開始malloc的內存,goto一直都是一個比較簡便的方法:
int foo() { somestruct* ptr = malloc(...); dosomething...; if(error) { goto END; } dosomething...; if(error) { goto END; } dosomething...; END: free(ptr); return 0; }由于goto不符合軟件工程的結構化(bug菌PS:其實在Linux里面goto用得非常廣泛的,可以參考下(點擊藍色字體):goto關鍵字你不知道的"那些事"(C語言提升)),而且有可能使得代碼難懂,所以很多人都不倡導使用,那這個時候就可以用do{}while(0)來進行統一的管理:
int foo() { somestruct* ptr = malloc(...); do{ dosomething...; if(error) { break; } dosomething...; if(error) { break; } dosomething...; }while(0); free(ptr); return 0; }這里將函數主體使用do()while(0)包含起來,使用break來代替goto,后續的處理工作在while之后,就能夠達到同樣的效果。
3、避免空宏引起的warning
內核中由于不同架構的限制,很多時候會用到空宏,在編譯的時候,空宏會給出warning,為了避免這樣的warning,就可以使用do{}while(0)來定義空宏:
#defineEMPTYMICROdo{}while(0)4、定義一個單獨的函數塊來實現復雜的操作: 當你的功能很復雜,變量很多你又不愿意增加一個函數的時候,使用do{}while(0);,將你的代碼寫在里面,里面可以定義變量而不用考慮變量名會同函數之前或者之后的重復。
審核編輯:劉清
聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規問題,請聯系本站處理。
舉報投訴
-
LINUX內核
+關注
關注
1文章
316瀏覽量
21619 -
預處理
+關注
關注
0文章
33瀏覽量
10473
原文標題:do{...} while(0) 的四大使用場景
文章出處:【微信號:c-stm32,微信公眾號:STM32嵌入式開發】歡迎添加關注!文章轉載請注明出處。
發布評論請先 登錄
相關推薦
C語言中while和do-while循環的用法
循環是一種重要的控制結構,可以使程序重復執行一段代碼,直到滿足特定條件為止。在C語言中,while和do-while是兩種常用的循環結構,本文將詳細介紹這兩種循環的用法。
發表于 08-18 16:35
?1716次閱讀
幾種LED調光協議分析及具體應用場景介紹
市面上主流幾種LED調光協議分析及具體應用場景介紹目前國內外的LED驅動已經不僅僅滿足照明需求,更多是去追求各種不同場景的應用,搭配各種數字協議,實現某種特定的功能,比如在汽車大燈的應用中,未為兼容
發表于 12-31 08:04
C語言宏定義使用do{}while(0)的好處是什么
C語言宏定義使用do{}while(0)的好處1. 概述經常寫項目代碼,有時需要用到宏定義,而宏定義的用法是否標準,則是會影響到是否能快速查錯以及代碼拓展性的問題。在宏定義的用法上大家為什么都推薦用
發表于 02-25 06:28
Java教程之如何進行Java中的do-while循環
我們知道當一開始循環條件就不滿足的時候,while循環一次也不會 執行。有的時候。我們有這樣的需要:無論如何循環都先執行一次,再判斷循環條件。 決定是否繼續執行.do-while循環就幫助我們滿足這樣的需要。
發表于 01-23 11:05
?7次下載
基于智慧城市的應用場景創新需求,組成全光自動駕駛網絡四大部分
全光城市2.0是基于智慧城市的應用場景創新需求,匹配城市通信基礎設施規劃,所提出的城市目標網絡架構,包括全光接入、全光錨點、全光交換、全光自動駕駛網絡四大組成部分。
發表于 09-10 09:56
?925次閱讀
do{...} while(0U) 這種代碼的作用和意義
在一些項目中,我們可能看到過很多,在學習的時候沒有見過的代碼,比如 do{...} while(0U) 這種代碼,在我們學習的時候可能很少見,但實際項目中卻存在很多類似代碼。 今天就來講講關于
C語言基礎:宏定義使用do{}while(0)的好處
C語言宏定義使用do{}while(0)的好處1. 概述 經常寫項目代碼,有時需要用到宏定義,而宏定義的用法是否標準,則是會影響到是否能快速查錯以及代碼拓展性的問題。在宏定義的用法上大家為什么都
發表于 01-13 13:06
?2次下載
C程序中do{}while(0)宏定義的作用
在嵌入式開發中,宏定義非常強大也非常便捷,如果正確使用可以讓你的工作事半功倍。然而,在很多的C程序中,你可能會看到不是那么直接的比較特殊一點的宏定義,比如do{}while(0)。
C語言-宏定義中使用do{...} while(0)到底圖個啥
在 Linux 內核中,經常會看到do{} while(0)這樣的語句,許多人開始都會疑惑,認為do{} while(
do{}while(0)只執行一次有意義嗎?
在嵌入式開發中,宏定義非常強大也非常便捷,如果正確使用可以讓你的工作事半功倍。然而,在很多的C程序中,你可能會看到不是那么直接的比較特殊一點的宏定義,比如do{}while(0)。
評論