程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C >> C語言入門知識 >> C語言在linux內核中do while(0)妙用之法

C語言在linux內核中do while(0)妙用之法

編輯:C語言入門知識

為什麼說do while(0) 妙?因為它的確就是妙,而且在linux內核中實現是相當的妙,我們來看看內核中的相關代碼:

#define db_error(fmt, ...) \
    do { 					\
		 fprintf(stderr, "(error): ");  \
		 fprintf(stderr, fmt, ##__VA_ARGS__); \
        } while (0)
這只是個普通的調試信息的輸出,有人便會認為,你這不是多此一舉嗎?去掉do while(0)不一樣也實現了嗎?其實不然,我們看看例子就清楚了,盡管很簡單:
int main(void)
{
	while(0)
	{
	  printf("hello world\n");	
	}
	
	do
	{
		printf("hello world1\n");
	}while(0);
	
	return 0 ; 
}
這是一段簡單到不能再簡單的代碼了,但還是要提一下,請看運行結果:

誰都知道第一個while(0)肯定是不會運行的,因為while()括號中的數值等於0,邏輯判定為假,即代碼塊中的hello world不會運行,但是do while(0)就不一樣了,do while(0)即使條件不成立,也會拼了老命的去執行一次!

也就是說,為什麼內核代碼要這樣來做,這是因為內核代碼采用do{}while(0);這種結構可以保證無論在什麼地方都可以正確的執行一次 ,這就是它用得最妙的地方,否則有時候調試程序的時候,單單的調試語句寫了沒打印其實是很正常的事情,不知道大家寫代碼的時候有沒有遇到過,反正我是遇到過了,後來就是用這樣的一種方法定位到錯誤點,順利改正。

\

代碼雖簡單,但是用好用精熟練使用不一定什麼時候都能想得到,越簡單的東西,有時候,適用價值還是很好的!大笑

分享以下我實現的調試輸出程序,以後可以拿來當模版開發了:

#include 
#include 
//內核代碼采用do{}while(0);這種結構可以保證無論在什麼地方都可以正確的執行一次 
#define db_error(fmt, ...) \
    do { 					\
		 fprintf(stderr, "(error): ");  \
		 fprintf(stderr, fmt, ##__VA_ARGS__); \
		 } while (0)
    
#define db_msg(fmt, ...) \
    do {              				\
		 fprintf(stdout, "(msg): "); \
		 fprintf(stdout, fmt, ##__VA_ARGS__); \
	   } while (0)
    
#define db_warn(fmt, ...) \
    do { fprintf(stdout, "(warn): "); \
		 fprintf(stdout, fmt, ##__VA_ARGS__);  \
	   } while (0)
    
#define db_debug(fmt, ...) \
    do {  				   \
		fprintf(stdout, "(debug): ");  \
		fprintf(stdout, fmt, ##__VA_ARGS__);  \
	   } while (0)
int main(void)
{
	db_error("h\n");
	db_warn("e\n");
	db_debug("llo\n");
	return 0 ;
}
運行結果:

調試信息在前,很快就可以知道在什麼地方打印的語句,方便DEBUG!迅速找到程序bug的定位!

\
 

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved