免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
12下一页
最近访问板块 发新帖
查看: 4260 | 回复: 11
打印 上一主题 下一主题

高手进来看一下,为什么kernel的这个macro要这样写,谢谢! [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2008-03-13 16:09 |只看该作者 |倒序浏览
10可用积分
小弟在阅读kernel的code时,发现有下面的macro的定义:

#define INIT_LIST_HEAD(ptr) do { \
        (ptr)->next = (ptr); (ptr)->prev = (ptr); \
} while (0)


让我感觉到奇怪的是,为什么这里要定义成do-while结构?
为什么不直接定义成下面这个样子呢?
#define INIT_LIST_HEAD(ptr) \
(ptr)->next = (ptr);\
(ptr)->prev = (ptr);


我认为我所定义的macro产生的code会更小!

论坛徽章:
0
2 [报告]
发表于 2008-03-13 19:53 |只看该作者
这里的do {} while 只是起到大括号的作用:wink:
do while还有一些妙用,可以代替goto语句,楼主感兴趣的话可以上网搜搜

论坛徽章:
0
3 [报告]
发表于 2008-03-14 16:14 |只看该作者
同意楼上的

想问一下 LZ的方法能通过编译不?

论坛徽章:
0
4 [报告]
发表于 2008-03-20 13:47 |只看该作者
LZ的方法加上了一个分号后就会有问题。

INIT_LIST_HEAD(ptr);

一般内核里都是这么写的,这个分号会有些麻烦的。

论坛徽章:
0
5 [报告]
发表于 2008-03-22 23:18 |只看该作者
我也对此处感到疑惑,自认为这个while(0)另有目的,内核中很多代码都相当有技巧的。

论坛徽章:
0
6 [报告]
发表于 2008-03-22 23:55 |只看该作者
路过学习下!!!~~~~~

论坛徽章:
0
7 [报告]
发表于 2008-03-23 18:04 |只看该作者

回复 #5 dwen20 的帖子

有什么目的?不介意分享一下吧

论坛徽章:
0
8 [报告]
发表于 2008-04-29 15:30 |只看该作者
内核中有很多类似的现象,也一直很迷惑,重点关注中。。。

论坛徽章:
0
9 [报告]
发表于 2008-04-29 16:33 |只看该作者
请参考<Linux内核源代码情景分析>第1章, 里面有详细的讲解, 讲述了为什么这么做的原因.

论坛徽章:
0
10 [报告]
发表于 2008-05-01 15:14 |只看该作者
这是由于宏定义的一些缺陷导致的:)如果没有do{ }while(0),那么在该预编译阶段宏定义被展开之后会出现问题(这里的展开就是替换)。举个例子如下:
#define M_FUNC(a, b, c)   a=1; b=2; c=3;

在具体代码中:
if (flag)
   M_FUNC(i,j,k)

else
   ...

用宏定义之后为:
if (flag)
    a=1;
    b=1;
    c=1;
else
   ...

这显然是不对的,也不是我们期望的!

如果使用了do {}while(0)定义为:
#define M_FUNC(a,b,c)  do {a=1; b=2; c=3}while(0)

就可以避免上述这个错误,这是do {}while(0)的一个主要用途~
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP