while(0)?

hanuix 2006-04-29 02:11:08
我在阅读FreeBSD的代码时常常看见在定义宏的时候(例如链表操作部分。。。)
#define MODULE_NAME_FUNC do { \
...... \
...... \
} while(0)

不知道这边的while(0)是做什么用的,请各位大虾赐教,谢谢:)
...全文
880 36 打赏 收藏 转发到动态 举报
写回复
用AI写文章
36 条回复
切换为时间正序
请发表友善的回复…
发表回复
feny911 2006-05-07
  • 打赏
  • 举报
回复
学到东西了
SammyLan 2006-05-06
  • 打赏
  • 举报
回复
#define swap(a,b)do{ \
int temp; \
temp=a; \
a=b; \
b=temp; \
}while(0)
作用:
1.防止命名污染:
inttemp;
othertype a;
macro(a);
要是去掉do while的,变成以下那样的话,容易则容易引起命名冲突
#define swap(a,b) \
int temp; \
temp=a; \
a=b; \
b=temp
当然你会说可以用以下方法避免命名冲突
#define swap(a,b){ \
int temp; \
temp=a; \
a=b; \
b=temp; \
}
但是他有引起了以下的问题
2.if/else中的错误:
if(a>b)
swap(a,b);
else
a++;
在这里的话,就会出现编译错误,当然你在这里swap后面不用";"号
SammyLan 2006-05-06
  • 打赏
  • 举报
回复
发错地方(=_=)
SammyLan 2006-05-06
  • 打赏
  • 举报
回复
可以说C++在OO方面不如JAVA
在底层方面不如C,ASM
在开发速度方面不如DELPHI,VB
在文本处理方面不如PERL
在运行方便方面不如脚本语言
在语法规范方面不如PASCAL
在人工智能描述方面不如LISP
在库的完备性方面不如JAVA,PERL

ADO,ADO.NET,OLE DB用什么写的?效率不如ASM,C,那你试一下用ASM或者纯C去实现(=_=),MSXML也不见得是用ASM,C,Java,DELPHI,或者VB开发的
C#的老祖宗--运行库是用什么开发的,是高效率的纯ASM,纯C,还是OO支持很好的Java,或者用于快速开发的DELPHI,VB,C#?
你用Java写一个大型服务器,银行电信的后台处理系统(=_=)
OO不如Java你用Java写个WOW,CS,效率不如ASM,纯C那你用ASM,纯C开发一个WOR,CS
你用纯ASM,纯C去开发一个ORACLE,或者用JAVA,DELHPI,VB实现个informix

你为什么不从另一个角度想呢:
C++在OO和开发速度方面强于ASM,C
在底层方面胜于JAVA,DELHPI,VB

作为一个老板,你当然是希望用JAVA,DELHPI,VB,因为那样可以从员工那里获取更多的利润--软件的售价一定,只能从员工那剥削更多的利润--聘请一个廉价的JAVA,DELPHI,VB程序员不难
在程序员的角度,完成同一个软件,用C++三个月,用JAVA两个月,同样的劳动成果,C++程序员可以拿三个月的薪水,你也只能拿两个月的工资.而Java程序员,只能停留在桌面应用,而C++程序员,可以随时转到底层开发
C++的优势不在于OO,也不在于效率,而是在于他和ASM/C语言的紧密耦合--学一种语法,会两种语言:这使他几乎适合任何一个领域:从底层开发到桌面应用,一路通杀
systemspy 2006-05-06
  • 打赏
  • 举报
回复
if (x > y)
MODULE_NAME_FUNC;
else
do_something();

if (x > y)
do {
if ( y == 0 )
{
}
} while(0);
else
do_something();

注意do while中的if配对问题,如果没有do while第二个if就和外面的else成对了,这不符合我们的原意
csrene 2006-05-06
  • 打赏
  • 举报
回复
学习了,UP!
avalonBBS 2006-05-02
  • 打赏
  • 举报
回复
宏定义 ...............do{................}while(0) <------不加分号

插入宏时可加分号,而编译器不会瞎鸡巴乱报~~
hanuix 2006-05-01
  • 打赏
  • 举报
回复
谢谢楼上各位大虾:)
Error_Code 2006-05-01
  • 打赏
  • 举报
回复
Why do a lot of #defines in the kernel use do { ... } while(0)?
There are a couple of reasons:
* (from Da.......
----------------
“a couple of reasons”寒.......-_-||

MARK了
#define FUNC do{\
...... \
...... \
/*这里几个反斜杠有什么作用?是不是非加不可呢?*/
sankt 2006-04-30
  • 打赏
  • 举报
回复
我在阅读FreeBSD的代码时常常看见在定义宏的时候(例如链表操作部分。。。)
#define MODULE_NAME_FUNC do { \
...... \
...... \
} while(0)

不知道这边的while(0)是做什么用的,请各位大虾赐教,谢谢:)

//===========
主要是让宏里面的语句执行一遍.

/*
* 难道不这样写可能执行多遍?
* 偶对这个说法不太理解,请赐教,谢谢啦:)
*/

//===============

do-while循环是至少执行一次,
当它执行完一次后,发现条件不满足,立即退出循环.

liusujian02 2006-04-30
  • 打赏
  • 举报
回复
收藏一下
Wolf0403 2006-04-30
  • 打赏
  • 举报
回复
http://www.kernelnewbies.org/FAQ/DoWhile0

kernelnewbiew.org,不知道国内朋友能看到不。转贴下面。

Why do a lot of #defines in the kernel use do { ... } while(0)?

There are a couple of reasons:

* (from Dave Miller) Empty statements give a warning from the compiler so this is why you see #define FOO do { } while(0).
* (from Dave Miller) It gives you a basic block in which to declare local variables.
* (from Ben Collins) It allows you to use more complex macros in conditional code. Imagine a macro of several lines of code like:

#define FOO(x) \
printf("arg is %s\n", x); \
do_something_useful(x);

Now imagine using it like:

if (blah == 2)
FOO(blah);

This interprets to:

if (blah == 2)
printf("arg is %s\n", blah);
do_something_useful(blah);;

As you can see, the if then only encompasses the printf(), and the do_something_useful() call is unconditional (not within the scope of the if), like you wanted it. So, by using a block like do { ... } while(0), you would get this:

if (blah == 2)
do {
printf("arg is %s\n", blah);
do_something_useful(blah);
} while (0);

Which is exactly what you want.

* (from Per Persson) As both Miller and Collins point out, you want a block statement so you can have several lines of code and declare local variables. But then the natural thing would be to just use for example:

#define exch(x,y) { int tmp; tmp=x; x=y; y=tmp; }

However that wouldn't work in some cases. The following code is meant to be an if-statement with two branches:

if (x > y)
exch(x,y); // Branch 1
else
do_something(); // Branch 2

But it would be interpreted as an if-statement with only one branch:

if (x > y) { // Single-branch if-statement!!!
int tmp; // The one and only branch consists
tmp = x; // of the block.
x = y;
y = tmp;
}
; // empty statement
else // ERROR!!! "parse error before else"
do_something();

The problem is the semi-colon (;) coming directly after the block. The solution for this is to sandwich the block between do and while (0). Then we have a single statement with the capabilities of a block, but not considered as being a block statement by the compiler. Our if-statement now becomes:

if (x > y)
do {
int tmp;
tmp = x;
x = y;
y = tmp;
} while(0);
else
do_something();
Wolf0403 2006-04-30
  • 打赏
  • 举报
回复
回复人:qscj(求是车几) ( 一级(初级)) 信誉:100 2006-04-30 17:13:00 得分:0
?
应该是为了能把“0”更方便的变成其它值,也就是sankt(黄景天)所说的那样

把 0 变为其他值在一定程度上缺乏实际意义。。
herman~~ 2006-04-30
  • 打赏
  • 举报
回复
我的理解:
用来防止死循环的吧
hanuix 2006-04-30
  • 打赏
  • 举报
回复
小弟觉得如果要实现上面各位大虾说的功能,只需要加
{
}
即可
没有必要用do while
来实现吧
@_@|||
blh 2006-04-30
  • 打赏
  • 举报
回复
给你一个例子

#define test(n) do { (n)++; } while (0)


int main()
{
int n = 0;
test(n);
return 0;
}
qscj 2006-04-30
  • 打赏
  • 举报
回复
应该是为了能把“0”更方便的变成其它值,也就是sankt(黄景天)所说的那样
hanuix 2006-04-30
  • 打赏
  • 举报
回复
#define MODULE_NAME_FUNC do\

int i;
int j;

}while(0)

main()
{
int i;
int j;
MODULE_NAME_FUNC;
}

如果不加dowhile上面的代码就会出现int i重新定义的错误,加上dowhile就不会有这个问题。

所以dowhile一个很好的好处就是保证变量的生命期。

当然dowhile的用处不仅只有这些,还有很多。
比如在for中,如果for中使用了宏,而碰巧宏中包含;,那么如果不使用dowhile,多半
这个for语句会发生错误。

/******************************************************/

#define MODULE_NAME_FUNC {\

int i; \
int j; \

} \

main()
{
int i;
int j;
MODULE_NAME_FUNC;
}

这样写不也可以吗?
那为什么还要用while呢?
lei001 2006-04-30
  • 打赏
  • 举报
回复
宏定义的一个技巧
ChoiceYi 2006-04-30
  • 打赏
  • 举报
回复
还少了转义符```郁闷
下面为正确的
#define MODULE_NAME_FUNC do{ \
int i; \
int j; \
}while(0)

void main()
{
int i;
int j;
MODULE_NAME_FUNC;
}
加载更多回复(16)

33,311

社区成员

发帖
与我相关
我的任务
社区描述
C/C++ 新手乐园
社区管理员
  • 新手乐园社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧