嵌套对象偏移 将0强制转换为指针
来源:互联网 发布:2016年3月进出口数据 编辑:程序博客网 时间:2024/04/29 04:45
tempalte <typename D, typename B> struct Offset { enum {value= (B*)(D*)0 - (D*)0}; }; Derived* temp = new Derived; Base2* pBase2 = (char*)temp + Offset<Derived, Base2>::value;linux中container_of
linux中container_of(ptr, type, member)宏的作用是传入结构体类型type的域member地址ptr,返回该结构体变量的首地址,定义如下:
#define container_of(ptr, type, member) ({ \ const typeof( ((type *)0)->member ) *__mptr = (ptr); \ (type *)( (char *)__mptr - offsetof(type,member) );})
这个宏里面有2处事GNU C独有的特性:
1:typeof(x)的意思是取x的类型,GNU C支持而ANSI C不支持
2: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++)产生副作用
下面具体分析这个container_of的实现:
1:const typeof( ((type *)0)->member ) *__mptr = (ptr);定义一个和member相同类型的变量__mptr,并把member地址赋给它
2:#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)宏的作用是传入结构体类型TYPE和其中的域MEMBER,返回该域在结构体中的偏移地址
3:(type *)( (char *)__mptr - offsetof(type,member) );得到结构体的首地址,并强制转换成type*类型
测试程序如下:#include <stdio.h>
#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)
#define container_of(ptr, type, member) ({ \ const typeof( ((type *)0)->member ) *__mptr = (ptr); \ (type *)( (char *)__mptr - offsetof(type,member) );})
typedef struct CONTAIN_s{ char a; int b; char c[10];}CONTAIN_t;
int main(void){ CONTAIN_t *pcon; CONTAIN_t con = {'3', 4, "abc"}; pcon = container_of(&con.b, CONTAIN_t, b);
printf("addr &con %p, addr pcon %p\n", &con, pcon);
return 0;}
输出:addr &con 0xbfd4bad8, addr pcon 0xbfd4bad8
typeof关键字的用法
http://www.cublog.cn/u3/101356/showart_2081601.html
- 嵌套对象偏移 将0强制转换为指针
- Repeater嵌套无法将类型为“System.Data.DataRow”的对象强制转换为类型“System.Data.DataRowView
- 将指针强制类型转换为函数指针
- 把“0”强制转化为结构体指针类型得到成员变量的偏移量
- 无法将类型为“*Class”的 COM 对象强制转换为接口类型 失败原因.
- 无法将类型为“System.Xml.XmlComment”的对象强制转换为类型“System.Xml.XmlElement”。
- 错误:无法将类型为“System.DBNull”的对象强制转换为类型“System.Byte[]”。
- 无法将类型为“System.Web.UI.LiteralControl”的对象强制转换为类型“System.Web
- 无法将类型为“System.DBNull”的对象强制转换为类型“System.Byte[]”
- 错误处理--无法将类型为 master的对象强制转换为类型 master
- C# 无法将类型为“System.DBNull”的对象强制转换为类型“System.String”。
- 无法将类型为“System.__ComObject”的 COM 对象强制转换为类类型“mshtml.HTMLInputElementClass
- (转)无法将类型为“Excel.ApplicationClass”的 COM 对象强制转换为接口类型“Excel._Application”
- 解决 无法将类型为“Excel._Application的QueryInterface”的 COM 对象强制转换为接口类型
- 无法将类型为“Excel.ApplicationClass”的 COM 对象强制转换为接口类型“Excel._Application”
- 无法将类型为“Shell32.ShellClass”的 COM 对象强制转换为接口类型“Shell32.IShellDispatch 6”
- ArcEngine 无法将类型为"Systerm._ComObject"的对象强制转换为类型******
- 无法将类型为“DAL.LoginDAO”的对象强制转换为类型“IDAL.LoginIDAL
- linux 安装gcc g++ gdb
- mac下git与github简单使用
- Linux环境变量的设置和查看方法
- H264 Over RTP
- netstat 的一些问题
- 嵌套对象偏移 将0强制转换为指针
- struts做的记录当前在线用户,不可重复登录,并且可对在线用户进行强制下线
- Asp.net的登录验证方法Web.config访问权限配置
- eclipse junit
- 放入conn.asp中(拒绝攻击 万能Asp防注入代码)
- fatal error C1189: #error : Building MFC application with /MD[d] (CRT dll version) requires MFC sha
- 坑爹的"前端智勇大冲关"
- 不能将参数 1 从“char [128]”转换为“LPCTSTR”vs2012 宽字符 转换为多字节的设置
- C++模板使用介绍