c++中do{...}while(0)的意義和用法。本站提示廣大學習愛好者:(c++中do{...}while(0)的意義和用法)文章只能為提供參考,不一定能成為您想要的結果。以下是c++中do{...}while(0)的意義和用法正文
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();
};
如許乃至不會編譯經由過程。所以,許多人才網job.vhao.net采取了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不相符軟件工程的構造化,並且有能夠使得代碼難明,所以許多人都不提倡應用,那這個時刻便可以用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)來界說空宏:
#define EMPTYMICRO do{}while(0)
4、界說一個零丁的函數塊來完成龐雜的操作:
當你的功效很龐雜,變量許多你又不肯意增長一個函數的時刻,應用do{}while(0);,將你的代碼寫在外面,外面可以界說變量而不消斟酌變量名會同函數之前或許以後的反復。