免费注册 查看新帖 |

Chinaunix

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

container_of中的临时变量 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2006-11-06 11:39 |只看该作者 |正序浏览
/*
**先求得结构成员在与结构中的偏移量,然后根据成员变量的地址反过来得出属主结构变量的地址。
**
*/
#define container_of(ptr, type, member) ({                \
         const typeof( ((type *)0)->member ) *__mptr = (ptr);        \
         (type *)( (char *)__mptr - offsetof(type,member) );})


((type *)0)->member,它将0地址强制"转换"为type结构的指针,再访问到type结构中的member成员。在container_of宏中,它用来给typeof()提供参数(typeof()是gcc的扩展,和sizeof()类似),以获得member成员的数据类型;在offsetof()中,这个member成员的地址实际上就是type数据结构中member成员相对于结构变量的偏移量。

这是Linux Kernel里的代码,意思能理解。
但是,这里的__mptr有什么意义,没有它也能实现,用它有什么好处?

论坛徽章:
0
14 [报告]
发表于 2009-06-01 19:24 |只看该作者
大概是用来做类型检查的,如果传入其它类型的指针,会有警告信息。

从这看到的:http://ds9a.nl/klogbot/?year=200 ... day=5&hour=10.5

论坛徽章:
0
13 [报告]
发表于 2008-07-27 09:10 |只看该作者

回复 #12 lisan 的帖子

__mptr的作用: 我觉得是 防止使用者随便放一个指针进去,导致出错吧

论坛徽章:
0
12 [报告]
发表于 2006-11-06 18:46 |只看该作者
a++副作用可以理解。
这里的__mptr有没有别的作用?
/**
* container_of - cast a member of a structure out to the containing structure
* @ptr:        the pointer to the member.
* @type:        the type of the container struct this is embedded in.
* @member:        the name of the member within the struct.
*
*/
#define container_of(ptr, type, member) ({                        \
        const typeof( ((type *)0)->member ) *__mptr = (ptr);        \
        (type *)( (char *)__mptr - offsetof(type,member) );})

论坛徽章:
0
11 [报告]
发表于 2006-11-06 18:07 |只看该作者
原帖由 albcamus 于 2006-11-6 17:31 发表


根据info文档, 是你说的这个意思, 我上面的回复错了

你是想多了,呵呵。

论坛徽章:
0
10 [报告]
发表于 2006-11-06 18:07 |只看该作者
原帖由 seeLnd 于 2006-11-6 17:43 发表
很感谢mingyanguo 和 albcamus

借此帖再问一个,经常会在一些函数中看到使用一些临时变量:
  1. void func(int arg) {
  2.   int tmp = arg;
  3.   tmp++;
  4.   ...
  5. }
复制代码

当参数的值会改变时,就会使用一个临时 ...

我觉得有时候只是个人习惯。
这里这个,我不知道这能不能帮助编译器优化,如果是从汇编调用这个函数的话,这个函数对arg的修改在后续代码中是可见的,编译器可能因此对优化有顾虑(?),我没试过,瞎猜的。
而且现在编译器的优化能力很强,多用几个临时变量对寄存器的优化分配不会构成多少影响。
乱说乱说,希望没有误导别人,我没试过。

论坛徽章:
0
9 [报告]
发表于 2006-11-06 17:43 |只看该作者
很感谢mingyanguo 和 albcamus

借此帖再问一个,经常会在一些函数中看到使用一些临时变量:
  1. void func(int arg) {
  2.   int tmp = arg;
  3.   tmp++;
  4.   ...
  5. }
复制代码

当参数的值会改变时,就会使用一个临时变量,好像是在防止arg的值被更改,
个人看不出来有tmp什么必要,
一直不是很清楚为什么,个人猜测是防止编译器优化,不知对不对。

[ 本帖最后由 seeLnd 于 2006-11-6 17:44 编辑 ]

论坛徽章:
0
8 [报告]
发表于 2006-11-06 17:31 |只看该作者
原帖由 mingyanguo 于 2006-11-6 17:28 发表


  1. #define FOO(x) BAR(x)

  2. FOO(a++);
复制代码

a++就是有副作用。


根据info文档, 是你说的这个意思, 我上面的回复错了

论坛徽章:
0
7 [报告]
发表于 2006-11-06 17:29 |只看该作者

  1. #define max(a, b) (a>b?a:b)
  2. #define mymax(a, b) ({typeof(a) _a = a, _b = b, _c; _c = _a>_b?_a:_b; _c;})



  3. int main()
  4. {
  5.         printf("max is %d\n", max(4, 8.3));
  6.         printf("mymax is %d\n", mymax(4, 8.3));
  7.         return 0;
  8. }
复制代码

[root@localhost ~]# ./a.out
max is 1251901440
mymax is 8


我猜测应该是这个意思。

论坛徽章:
0
6 [报告]
发表于 2006-11-06 17:28 |只看该作者
原帖由 seeLnd 于 2006-11-6 17:19 发表
没有看太明白,请问albcamus,
“But this definition computes either A or B twice,
with bad results if the operand has side effects.”

这句话怎么理解?

“A或B任何一个都会被计算两次,如果操作数 ...

  1. #define FOO(x) BAR(x)

  2. FOO(a++);
复制代码

a++就是有副作用。
  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP