这样写是不是耍宝,还是有深意的#define XX do{......;}while(0)
答案:4 悬赏:80 手机版
解决时间 2021-03-26 14:26
- 提问者网友:城市野鹿
- 2021-03-25 20:33
这样写是不是耍宝,还是有深意的#define XX do{......;}while(0)
最佳答案
- 五星知识达人网友:酒安江南
- 2021-03-25 21:15
如果你想在宏中包含多个语句,可能会这样写:
#define do_something() \
do_a(); \
do_b();
这样你就可以用 do_somethin() 来执行一系列操作.
但这样会有个问题: 如果你下面这样用这个宏地话:
if (...)
do_something();
当宏被展开后就变成:
if (...)
do_a();
do_b();
发现问题没? 原代码的目的是想在 if 为真的时候执行 do_a() 和 do_b(), 但现在呢? 只有 do_a() 在条件语句中, do_b() 任何时候都会执行的.
这时你可能会将那个宏改进一下:
#define do_something() { \
do_a(); \
do_b(); \
}
看样子行了, 是吗? 如果我这个宏是这个样子的呢:
#define do_something() { \
if (a) \
do_a(); \
else \
do_b();
}
这么使用:
if (...)
do_something();
else {
...
}
宏展开后:
if (...)
{
if (a)
do_a();
else
do_b();
}; else {
}
注意到第二个 else 前边那个分号了吗?
所以有人想到了用 do { } while (0) 来解决这个问题, do {} while 语句是需要分号来结束的, 另外, 现代编译器的优化模块能够足够聪明地注意到这个循环只会执行一次而将其优化掉.
综上所述, do { } while(0) 这个技术就是为了类似的宏可以在任何时候使用.
注: 如果你看过 linux 内核源代码, 这个技巧非常常见
#define do_something() \
do_a(); \
do_b();
这样你就可以用 do_somethin() 来执行一系列操作.
但这样会有个问题: 如果你下面这样用这个宏地话:
if (...)
do_something();
当宏被展开后就变成:
if (...)
do_a();
do_b();
发现问题没? 原代码的目的是想在 if 为真的时候执行 do_a() 和 do_b(), 但现在呢? 只有 do_a() 在条件语句中, do_b() 任何时候都会执行的.
这时你可能会将那个宏改进一下:
#define do_something() { \
do_a(); \
do_b(); \
}
看样子行了, 是吗? 如果我这个宏是这个样子的呢:
#define do_something() { \
if (a) \
do_a(); \
else \
do_b();
}
这么使用:
if (...)
do_something();
else {
...
}
宏展开后:
if (...)
{
if (a)
do_a();
else
do_b();
}; else {
}
注意到第二个 else 前边那个分号了吗?
所以有人想到了用 do { } while (0) 来解决这个问题, do {} while 语句是需要分号来结束的, 另外, 现代编译器的优化模块能够足够聪明地注意到这个循环只会执行一次而将其优化掉.
综上所述, do { } while(0) 这个技术就是为了类似的宏可以在任何时候使用.
注: 如果你看过 linux 内核源代码, 这个技巧非常常见
全部回答
- 1楼网友:封刀令
- 2021-03-26 00:18
为了让这个代码只执行一次,并且你看有{},在{}里面的对象和变量都会在出来时释放,而不是到函数结束才释放,为了节约内存啊
- 2楼网友:渊鱼
- 2021-03-25 23:18
DO WHILE和WHILE不同 里面的代码会先被执行一次 然后在与条件进行判断
所以说会执行一次 不过为什么要加do{和}while(0)就不懂了 可能为了调试方便吧
所以说会执行一次 不过为什么要加do{和}while(0)就不懂了 可能为了调试方便吧
- 3楼网友:一把行者刀
- 2021-03-25 21:47
比如定义宏,#define FREE1(p) if (p) free (p)
然后这样调用:
if (expression)
FREE1(p);
else
printf(“expression was false.\n”) ;
展开:
if (expression)
if (p) free (p);
else
printf(“expression was false.\n”) ;
看看else和第二个if匹配了,错了吧,呵呵!
-
换成这样定义,#define FREE1(p) do{if (p) free (p);}while(0)
展开:
if (expression)
do{if (p) free (p);}while(0);
else
printf(“expression was false.\n”) ;
这样才对嘛!
要相信:真正高手们的程序绝对没有"耍宝"的!
然后这样调用:
if (expression)
FREE1(p);
else
printf(“expression was false.\n”) ;
展开:
if (expression)
if (p) free (p);
else
printf(“expression was false.\n”) ;
看看else和第二个if匹配了,错了吧,呵呵!
-
换成这样定义,#define FREE1(p) do{if (p) free (p);}while(0)
展开:
if (expression)
do{if (p) free (p);}while(0);
else
printf(“expression was false.\n”) ;
这样才对嘛!
要相信:真正高手们的程序绝对没有"耍宝"的!
我要举报
如以上回答内容为低俗、色情、不良、暴力、侵权、涉及违法等信息,可以点下面链接进行举报!
点此我要举报以上问答信息
大家都在看
推荐资讯