语言#Linux"/>
C语言#Linux
代码复制于Linux内核:tools/include/linux/kernel.h
作用图:
功能:
- 1、typeof是编译器扩展的特性(推断出类型),.html#Typeof
- 2、container_of:1、先报地址强制转换为特定成员地址,变量前_为了不冲突 2、计算成员偏移字节 3、再转换为char*,为了进行字节单位的地址运算 4、最终转换为结构体类型即可。。。 5、整个宏是一个复合语句,最后一个子表达式的值就是整个表达式的值。(也是编译器扩展特性,.html)
#include <stdio.h>
#include <stdlib.h>//复制于:tools/include/linux/kernel.h#ifndef offsetof
#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)
#endif#ifndef container_of
/*** container_of - cast a member of a structure out to the containing structure* @ptr: the pointer to the member.* @type: the type of the container struct this is embedded in.* @member: the name of the member within the struct.**/
#define container_of(ptr, type, member) ({ \const typeof(((type *)0)->member) * __mptr = (ptr); \(type *)((char *)__mptr - offsetof(type, member)); })
#endif#ifndef max
#define max(x, y) ({ \typeof(x) _max1 = (x); \typeof(y) _max2 = (y); \(void) (&_max1 == &_max2); \_max1 > _max2 ? _max1 : _max2; })
#endif#define P_INT(a) printf("The int is: [%d]\n",a)typedef struct TestBuffer {int a;double b;struct InBuffer{int aa;double bb;}c;
}TestBuffer;struct InBuffer* getInBuffer() {TestBuffer *tbp = malloc(sizeof(*tbp));if(tbp == NULL) {exit(-1);}printf("在一个函数内,所以我知道 tbp的地址: [%p].\n",tbp);return &tbp->c;
}int main(int argc, char const *argv[])
{typeof(int) a = 10;P_INT(a);int offSetC = offsetof(TestBuffer, c);printf("成员c的地址,从结构体的地址开始算,偏移了 [%d] 个字节.\n", offSetC);struct InBuffer *inbp = getInBuffer();TestBuffer *tbp = container_of(inbp, TestBuffer, c);printf("在一个函数外,我只知道成员的地址,但是container_of可以帮我获取 结构体的地址: [%p].\n", tbp);free(tbp);return 0;
}
运行结果:
预处理后的语句,gcc -E
int main(int argc, char const *argv[])
{
// ....struct InBuffer *inbp = getInBuffer();TestBuffer *tbp = ({ const typeof(((TestBuffer *)0)->c) * __mptr = (inbp); (TestBuffer *)((char *)__mptr - ((size_t) &((TestBuffer *)0)->c)); });//....return 0;
}
更多推荐
C语言#Linux
发布评论