這里只針對單核CPU,linux內(nèi)核和其他一些開源的代碼中,經(jīng)常會遇到這樣的代碼:
do{
...
}while(0)
這樣的代碼一看就不是一個循環(huán),do..while表面上在這里一點意義都沒有,那么為什么要這么用呢?
實際上,do{...}while(0)的作用遠大于美化你的代碼。查了些資料,總結(jié)起來這樣寫主要有以下幾點好處:
1、輔助定義復(fù)雜的宏,避免引用的時候出錯: 舉例來說,假設(shè)你需要定義這樣一個宏:
#define DOSOMETHING()
foo1();
foo2();
這個宏的本意是,當調(diào)用DOSOMETHING()時,函數(shù)foo1()和foo2()都會被調(diào)用。但是如果你在調(diào)用的時候這么寫:
if(a > 0)
DOSOMETHING();
因為宏在預(yù)處理的時候會直接被展開,你實際上寫的代碼是這個樣子的:
if(a > 0)
foo1();
foo2();
這就出現(xiàn)了問題,因為無論a是否大于0,foo2()都會被執(zhí)行,導(dǎo)致程序出錯。那么僅僅使用{}將foo1()和foo2()包起來行么?
我們在寫代碼的時候都習(xí)慣在語句右面加上分號,如果在宏中使用{},代碼里就相當于這樣寫了:“ { ... } ; ”,展開后就是這個樣子 :
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對程序流進行統(tǒng)一的控制: 有些函數(shù)中,在函數(shù)return之前我們經(jīng)常會進行一些收尾的工作,比如free掉一塊函數(shù)開始malloc的內(nèi)存,goto一直都是一個比較簡便的方法:
int foo()
{
somestruct* ptr = malloc(...);
dosomething...;
if(error)
{
goto END;
}
dosomething...;
if(error)
{
goto END;
}
dosomething...;
END:
free(ptr);
return 0;
}
由于goto不符合軟件工程的結(jié)構(gòu)化(bug菌PS:其實在Linux里面goto用得非常廣泛的,可以參考下(點擊藍色字體):goto關(guān)鍵字你不知道的"那些事"(C語言提升)),而且有可能使得代碼難懂,所以很多人都不倡導(dǎo)使用,那這個時候就可以用do{}while(0)來進行統(tǒng)一的管理:
int foo()
{
somestruct* ptr = malloc(...);
do{
dosomething...;
if(error)
{
break;
}
dosomething...;
if(error)
{
break;
}
dosomething...;
}while(0);
free(ptr);
return 0;
}
這里將函數(shù)主體使用do()while(0)包含起來,使用break來代替goto,后續(xù)的處理工作在while之后,就能夠達到同樣的效果。3、避免空宏引起的warning
內(nèi)核中由于不同架構(gòu)的限制,很多時候會用到空宏,在編譯的時候,空宏會給出warning,為了避免這樣的warning,就可以使用do{}while(0)來定義空宏:
#defineEMPTYMICROdo{}while(0)
4、定義一個單獨的函數(shù)塊來實現(xiàn)復(fù)雜的操作: 當你的功能很復(fù)雜,變量很多你又不愿意增加一個函數(shù)的時候,使用do{}while(0);,將你的代碼寫在里面,里面可以定義變量而不用考慮變量名會同函數(shù)之前或者之后的重復(fù)。
審核編輯:劉清
聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請聯(lián)系本站處理。
舉報投訴
-
LINUX內(nèi)核
+關(guān)注
關(guān)注
1文章
321瀏覽量
23214 -
預(yù)處理
+關(guān)注
關(guān)注
0文章
33瀏覽量
10814
原文標題:do{...} while(0) 的四大使用場景
文章出處:【微信號:c-stm32,微信公眾號:STM32嵌入式開發(fā)】歡迎添加關(guān)注!文章轉(zhuǎn)載請注明出處。
發(fā)布評論請先 登錄
相關(guān)推薦
熱點推薦
C語言中while和do-while循環(huán)的用法
循環(huán)是一種重要的控制結(jié)構(gòu),可以使程序重復(fù)執(zhí)行一段代碼,直到滿足特定條件為止。在C語言中,while和do-while是兩種常用的循環(huán)結(jié)構(gòu),本文將詳細介紹這兩種循環(huán)的用法。
發(fā)表于 08-18 16:35
?2886次閱讀
CW32L0系列都有哪些應(yīng)用場景?有哪些優(yōu)勢?
目前芯源的低功耗MCU比較火爆,就是CW32L0系列都有哪些應(yīng)用場景?有哪些優(yōu)勢?
發(fā)表于 11-14 06:03
C語言宏定義使用do{}while(0)的好處是什么
C語言宏定義使用do{}while(0)的好處1. 概述經(jīng)常寫項目代碼,有時需要用到宏定義,而宏定義的用法是否標準,則是會影響到是否能快速查錯以及代碼拓展性的問題。在宏定義的用法上大家為什么都推薦用
發(fā)表于 02-25 06:28
Proteus之do-while語句的應(yīng)用
Proteus之do-while語句的應(yīng)用,很好的Proteus資料,快來學(xué)習(xí)吧。
發(fā)表于 04-18 14:49
?0次下載
Java教程之如何進行Java中的do-while循環(huán)
我們知道當一開始循環(huán)條件就不滿足的時候,while循環(huán)一次也不會 執(zhí)行。有的時候。我們有這樣的需要:無論如何循環(huán)都先執(zhí)行一次,再判斷循環(huán)條件。 決定是否繼續(xù)執(zhí)行.do-while循環(huán)就幫助我們滿足這樣的需要。
發(fā)表于 01-23 11:05
?7次下載
do{...} while(0U) 這種代碼的作用和意義
在一些項目中,我們可能看到過很多,在學(xué)習(xí)的時候沒有見過的代碼,比如 do{...} while(0U) 這種代碼,在我們學(xué)習(xí)的時候可能很少見,但實際項目中卻存在很多類似代碼。 今天就來講講關(guān)于
C語言基礎(chǔ):宏定義使用do{}while(0)的好處
C語言宏定義使用do{}while(0)的好處1. 概述 經(jīng)常寫項目代碼,有時需要用到宏定義,而宏定義的用法是否標準,則是會影響到是否能快速查錯以及代碼拓展性的問題。在宏定義的用法上大家為什么都
發(fā)表于 01-13 13:06
?2次下載
C程序中do{}while(0)宏定義的作用
在嵌入式開發(fā)中,宏定義非常強大也非常便捷,如果正確使用可以讓你的工作事半功倍。然而,在很多的C程序中,你可能會看到不是那么直接的比較特殊一點的宏定義,比如do{}while(0)。
如何去區(qū)分while與do while 的用法
如何去區(qū)分while 與 do while 的用法。
2 方法
Do while和
C語言-宏定義中使用do{...} while(0)到底圖個啥
在 Linux 內(nèi)核中,經(jīng)常會看到do{} while(0)這樣的語句,許多人開始都會疑惑,認為do{} while(
do{}while(0)只執(zhí)行一次有意義嗎?
在嵌入式開發(fā)中,宏定義非常強大也非常便捷,如果正確使用可以讓你的工作事半功倍。然而,在很多的C程序中,你可能會看到不是那么直接的比較特殊一點的宏定義,比如do{}while(0)。
do{...} while(0)的四大使用場景介紹
評論