免费注册 查看新帖 |

Chinaunix

广告
  平台 论坛 博客 文库
12下一页
最近访问板块 发新帖
查看: 5785 | 回复: 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
2 [报告]
发表于 2006-11-06 14:01 |只看该作者
info gcc -> C Extensions -> Statement Exprs

论坛徽章:
0
3 [报告]
发表于 2006-11-06 14:19 |只看该作者
原帖由 albcamus 于 2006-11-6 14:01 发表
info gcc -> C Extensions -> Statement Exprs

不明白
#define container_of(ptr, type, member) ({                \         
         (type *)( (char *)ptr- offsetof(type,member) );})

不行吗?

论坛徽章:
0
4 [报告]
发表于 2006-11-06 15:02 |只看该作者
The last thing in the compound statement should be an expression
followed by a semicolon; the value of this subexpression serves as the
value of the entire construct.  (If you use some other kind of statement
last within the braces, the construct has type `void', and thus
effectively no value.)

This feature is especially useful in making macro definitions "safe"
(so that they evaluate each operand exactly once).  For example, the
"maximum" function is commonly defined as a macro in standard C as
follows:

     #define max(a,b) ((a) > (b) ? (a) : (b))

But this definition computes either A or B twice, with bad results if
the operand has side effects.  In GNU C, if you know the type of the
operands (here taken as `int'), you can define the macro safely as
follows:

     #define maxint(a,b) \
       ({int _a = (a), _b = (b); _a > _b ? _a : _b; })

Embedded statements are not allowed in constant expressions, such as
the value of an enumeration constant, the width of a bit-field, or the
initial value of a static variable.

If you don't know the type of the operand, you can still do this, but
you must use `typeof'

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

这句话怎么理解?

“A或B任何一个都会被计算两次,如果操作数有副作用就会产生一个错的结果. ”

这个"副作用"具体指什么?

论坛徽章:
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++就是有副作用。

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


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

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

a++就是有副作用。


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

论坛徽章:
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
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的修改在后续代码中是可见的,编译器可能因此对优化有顾虑(?),我没试过,瞎猜的。
而且现在编译器的优化能力很强,多用几个临时变量对寄存器的优化分配不会构成多少影响。
乱说乱说,希望没有误导别人,我没试过。
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP