hust_jixing 2015-12-28 01:38 采纳率: 0%
浏览 1737
已采纳

关于linux kernel中的container_of宏的困惑

#define container_of(ptr, type, member) ({ \
const typeof( ((type *)0)->member ) *__mptr = (ptr); \
(type *)( (char *)__mptr - offsetof(type,member) );})

最近在看linux kernel中的链表操作, 看到了如上这个宏, 其实表达的意思很简单, 但是他要用一个__mptr来指向ptr甚是不解?实测如下宏也是可行的:
#define container_of(ptr, type, member) ({ \
(type *)( (char *)ptr - offsetof(type,member) );})

内核用一个临时const变量来存储ptr是为什么啊? 并且第一步还要强行获得ptr的对象类型, 第二步又将mptr强转成char *类型, 就我目前的知识来看这种操作好鸡肋, 内核这样做是适应编译器的操作“习惯”吗? 还是说有其它的“难言之隐“?有大神能帮忙解答一下吗? 
  • 写回答

1条回答 默认 最新

  • 不够努力的撸舍 2016-02-01 06:39
    关注

    GNU C把包含在括号里的复合语句看做是一个表达式,称为语句表达式,它可以出现在任何允许表达式的地方。我们可以在语句表达式中使用原本只能在复合语句中使用的循环变量、局部变量等

    例如int aa = ({3; 43-5;});使用不支持GNU C的编译器会报错,而使用gcc会得到aa为38
    利用GNU C的这种特性,我们可以避免一些宏定义产生副作用,如使用

    #define min_t(type,x,y) \
    ({type x=(x); type __y=(y);x<__y?__x:__y})
    代替

    #define min(x,y) ((x)<(y)?(x):(y))
    可避免传入min(a++,b++)产生副作用

    所以, const typeof( ((type *)0)->member ) *__mptr = (ptr);是为了确保不会得到任何ptr表达式,都不会有副作用。

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥100 有人会搭建GPT-J-6B框架吗?有偿
  • ¥15 求差集那个函数有问题,有无佬可以解决
  • ¥15 【提问】基于Invest的水源涵养
  • ¥20 微信网友居然可以通过vx号找到我绑的手机号
  • ¥15 寻一个支付宝扫码远程授权登录的软件助手app
  • ¥15 解riccati方程组
  • ¥15 display:none;样式在嵌套结构中的已设置了display样式的元素上不起作用?
  • ¥15 使用rabbitMQ 消息队列作为url源进行多线程爬取时,总有几个url没有处理的问题。
  • ¥15 Ubuntu在安装序列比对软件STAR时出现报错如何解决
  • ¥50 树莓派安卓APK系统签名