1. container_of是Linux内核中实现的宏,不是C语言的标准函数。不能跨平台。
#define container_of(ptr, type, member) ({ \
const typeof( ((type *)0)->member ) *__mptr = (ptr) \
(type *)( (char *)__mptr - offsetof(type,member) )})
2. typeof是GNU C的扩展,不是ISO标准中运悔的函数。用gcc编译可以跨平台。
3. offsetof是C语言标准库中的宏,定义在慧悄派头文件stddef.h中前贺。可以跨平台。
offsetof宏的简介定义
在stddef.h头文件中,该宏的完整说明如下:
#ifdef __cplusplus
#ifdef _WIN64
#define offsetof(s,m) (size_t)( (ptrdiff_t)&reinterpret_cast<const volatile char&>((((s *)0)->m)) )
#else
#define offsetof(s,m) (size_t)&reinterpret_cast<const volatile char&>((((s *)0)->m))
#endif
#else
#ifdef _WIN64
#define offsetof(s,m) (size_t)( (ptrdiff_t)&(((s *)0)->m) )
#else
#define offsetof(s,m) (size_t)&(((s *)0)->m)
#endif
#endif /* __cplusplus */
功能
在msdn上,该宏被写作:
size_t offsetof( structName, memberName )
第一个参数是结构体的名字,第二个参数是结构体成员的名字。该宏返回结构体structName中成员memberName的偏移量。偏移量是size_t类型的。
编辑本段
程序示例
#include <stdio.h>
#include <stddef.h>
typedef struct
{
int iVal
int iVal2
}Test
typedef struct
{
char ch
int iNum
}Test2
int main(void)
{
Test t = {1, 2}
Test2 t2 = {'t', 100}
printf("\naddress of t : %p\naddress of t.iVal : %p\naddress of t.iVal2: %p\n\n", &t, &(t.iVal), &(t.iVal2))
printf("offset of iVal in t: %p\n", offsetof(Test, iVal))
printf("offset of iVal2 in t: %p\n", offsetof(Test, iVal2))
printf("\naddress of t2 : %p\naddress of t2.ch : %p\naddress of t2.iNum: %p\n\n", &t, &(t2.ch), &(t2.iNum))
printf("offset of ch in t2: %p\n", offsetof(Test2, ch))
printf("offset of iNum in t2: %p\n", offsetof(Test2, iNum))
return 0
}
在VS2005中输出:
address of t : 0012FF10
派核address of t.iVal : 0012FF10
address of t.iVal2: 0012FF14
offset of iVal in t: 00000000
offset of iVal2 in t: 00000004
address of t2 : 0012FF10
address of t2.ch : 0012FF00
address of t2.iNum: 0012FF04
offset of ch in t2: 00000000
尘早掘 offset of iNum in t2: 00000004
需要注意的是,Test2中iNum成员的睁喊偏移量
有的。我们可以将linux/kernel.h头文件包含进来,直接在用局桥户空间携腔测试这个宏的巧妙...那个__compiler_offsetof原辩腊衫型是__builtin_offsetof这个是GCC编译器所特有的。欢迎分享,转载请注明来源:内存溢出
评论列表(0条)