繼上篇簡單提了些macro和gnu extension,我們再來看個我覺得很重要的例子 => container_of, offsetof, typeoff
(參考jserv老師Linux 核心原始程式碼巨集: container_of)
//include/linux/stddef.h
#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)
typedef struct Fruit{
char name[13];//default alignment is 4 bytes
int date;
int price;
} fruit_t;
// stdout : (size_t) &((fruit_t *)0)->price = 0x14
// 0x14 = 0x10(name[13]) + 0x4(date)
//include/linux/kernel.h
#define container_of(ptr, type, member) ({ \
const typeof( ((type *)0)->member ) *__mptr = (ptr); \
(type *)( (char *)__mptr - offsetof(type,member) );})
//ptr = apple->price
//type = fruit_t
//member = price
假設地址分佈如下
|----|0xa100| apple
|----|0xa110 |name
|----|0xa114 |date
|----|0xa118 |price
則__mptr = 0xa114,
而offsetof(fruit_t, price) = 0x14,
所以container_of(apple->price, fruit_t, price) = 0xa100 = apple !
基本指令: and(&), or(|), shift left(<<), shift right(>>), xor(^), not(~)
明天再補一些常用技巧,接著再講一些compiler, linker就要快點進入cpu和os了!