tapeof

typeof為獲取的目標的類型,用於聲明變數類型。

定義

此處此類型為char

見:  

關於container_of見kernel.h中:

/**

* 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) );})

container_of在Linux Kernel中的套用非常廣泛,它用於獲得某結構中某成員的入口地址.

關於offsetof見stddef.h中:

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

TYPE是某struct的類型 0是一個假想TYPE類型struct,MEMBER是該struct中的一個成員. 由於該struct的基地址為0, MEMBER的地址就是該成員相對與struct頭地址的偏移量.

關於typeof,這是gcc的C語言擴展保留字,用於聲明變數類型.

const typeof( ((type *)0->member ) *__mptr = (ptr);意思是聲明一個與member同一個類型的指針常量 *__mptr,並初始化為ptr.

(type *)( (char *)__mptr - offsetof(type,member) );意思是__mptr的地址減去member在該struct中的偏移量得到的地址, 再轉換成type型指針. 該指針就是member的入口地址了.

示例

例一;

container_of宏定義在[include/linux/kernel.h]中:

#define container_of(ptr, type, member) \

const typeof( ((type *)0)->member ) *__mptr = (ptr); \

(type *)( (char *)__mptr - offsetof(type,member) );

offsetof宏定義在[include/linux/stddef.h]中:

#define offsetof(type, member) ((size_t) &((type *)0)->member)

下面用一個測試程式test.c來說明

#include

struct student{

char name[20];

char sex;

}stu={"zhangsan",'m'};

main()

{

struct student *stu_ptr; //存儲container_of宏的返回值

int offset; //存儲offsetof宏的返回值

//下面三行代碼等同於 container_of(&stu.sex,struct student, sex )參數帶入的情形

const typeof(((struct student*)0)->sex) *_mptr = &stu.sex;

//首先定義一個 _mptr指針, 類型為struct student結構體中sex成員的類型

//typeof 為獲取(((struct student*)0)->sex)的類型,此處此類型為char

//((struct student*)0)在offsetof處講解

offset = (int)(&((struct student *)0)->sex);

/*((struct student*)0)為 把 0地址 強制轉化為指向student結構體類型的指針

該指針從地址 0 開始的 21個位元組用來存放name 與 sex(char name〔20〕與 char sex共21位元組)

sex存放在第20個位元組出(從0位元組開始)

&((struct student *)0)->sex 取出sex地址(此處即為20) 並強制轉化為整形

所以offset為20,後面的printf結果將證明這一點*/

stu_ptr = (struct student *)((char*)_mptr - offset);

/*((char*)_mptr - offset)此處先把_mptr指針轉化為字元形指針

(為什麼這么做呢? 如果_mptr為整形指針 _mptr - offset 相當於減去 sizeof(int)*offset個位元組)

減去 offset值 相當於 得到_mptr所在結構體的首地址(即stu的地址)

然後我們把 該地址 強制轉化為 struct student類型即可正常使用了*/

printf("offsetof stu.sex = %d\n",offset);

printf("stu_ptr->name:%s\tstu_ptr->sex:%c\n", stu_ptr->name, stu_ptr->sex);

return 0;

}

相關詞條

相關搜尋

熱門詞條

聯絡我們