您现在的位置: 爱51代码网 >> 范文 >> 文章正文
char型的__mptr减ulong的偏移量可以得到该结构体的地址吗

#define list_entry(ptr, type, member) \ 
        container_of(ptr, type, member)

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

#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)

size_t 是unsigned long
typedef struct xxx
{
type1 member;
……(结构体中其他域)
}type;
定义变量:
type a;
type * b;
type1 * ptr;

&((type *)0)->member取得的是个什么,为什么要转为u long
为什么要用__mptr当中间变量,不直接用ptr。
最后用char型的__mptr减ulong的偏移量可以得到该结构体的地址吗?

首先第一个问题是 通过 typeof( ((type *)0)->member ) 获取member成员的类型,
第二个问题是 如果直接用ptr  做偏移, ptr本身指向就变了
第三个问题是 获取到的是这个结构起始地址

2. 为什么需要中间变量_mtpr,因为传入的参数ptr,不见得就是个简单的指针变量,也有可能是个表达式(因为这是宏)。
比如contailer_of(ptr + 1, struct XXX, member),
如果去掉_mptr,那么就变成了(char *)ptr + 1 - offset,结果就是错误的(应该是((char *)(ptr + 1)) - offset,注意括号)

3. 为什么要转换成char *,因为在c语言里面,(((type *)ptr) - offset)  == ((char *)ptr) - sizeof(type) * offset。
不是往前挪offset个字节,而是往前挪offset个结构。
显然这些需要的是字节语义。

因为 成员的地址 = 结构的地址 + 字节偏移, 所以 结构的地址 = 成员的地址 - 字节编译。(以字节为单位计算)

  • 上一篇文章:

  • 下一篇文章: 没有了
  • 最新文章 热点文章 相关文章
    SharePoint 2013 Search REST AP
    SharePoint如何搜索指定的爬网内
    weblogic Servlet: "action" fai
    webdav 与exchange通信失败未找到
    SharePoint2013文档库可以直接存
    Unable to write data to the tr
    asp.net中listbox的items.count属
    C#不是每次查询数据是不是被缓存
    ASP.NET发布后能加载引用的js文件
    Hadoop2.2.0在eclipse控制台没有
    SharePoint 2013 Search REST AP
    SharePoint如何搜索指定的爬网内
    weblogic Servlet: "action" fai
    webdav 与exchange通信失败未找到
    SharePoint2013文档库可以直接存
    Unable to write data to the tr
    asp.net中listbox的items.count属
    C#不是每次查询数据是不是被缓存
    ASP.NET发布后能加载引用的js文件
    Hadoop2.2.0在eclipse控制台没有
    Linux下使用mono支持Asp.Net
    Ubuntu下载软件仓库信息失败
    ubuntu14.10 如何设置交叉编
    shell如何判断程序占用了80%
    VOIP如何回声消除
    根目录下无法执行make insta
    查看ARM s3c2440的代码哪些文
    VM中RedHat6.3无法连接外网
    linux如何判断标准输入缓冲区
    vi编译一个十六进制为0x80的
     



    设为首页 | 加入收藏 | 网站地图 | 友情链接 |