|
|
|
|
 帮忙解释一下这个宏的一些细节。 - onlyflyer1 [ 2006-04-28 13:30 | 759 byte(s)]
 Re: 帮忙解释一下这个宏的一些细节。 - zhllg [ 2006-04-29 13:20 | 272 byte(s)]
 Re: 帮忙解释一下这个宏的一些细节。 - newroot [ 2006-04-29 16:03 | 681 byte(s)]
 Re: 帮忙解释一下这个宏的一些细节。 - zhllg [ 2006-04-29 17:48 | 10 byte(s)]
 Re: 帮忙解释一下这个宏的一些细节。 - ddd [ 2006-04-28 22:01 | 98 byte(s)]
 Re: 帮忙解释一下这个宏的一些细节。 - gogoliu [ 2006-04-28 14:12 | 763 byte(s)]
 Re: 帮忙解释一下这个宏的一些细节。 - onlyflyer1 [ 2006-04-28 16:12 | 33 byte(s)]
|
|
|
|
[Original]
[Print]
[Top]
|
#define OFFSET(structure, member) ((int) &(((structure *)0)->member))
这个宏是取得一个结构中的偏移,下面的程序会输出8(考虑到内存对齐)
#include <stdio.h>
#define OFFSET(structure, member) ((int) &(((structure *)0)->member))
typedef struct test
{
int a;
char b;
float c;
}TEST;
int main()
{
int i = OFFSET(TEST, c);
printf("%d
", i);
}
谁能够将#define OFFSET(structure, member) ((int) &(((structure *)0)->member)) 彻底剖析一下啊。还有有谁能用sizeof实现OFFSET的另一个版本,上次我去一个公司笔试的时候被问到这个问题,最后没有答出。
|
|
|
[Original]
[Print]
[Top]
|
|
[Original]
[Print]
[Top]
|
看明白了宏定义,解释一下:
这个宏定义的作用是取得某个结构中的某个成员在该结构中的偏移。要实现这个功能很直接会想到用该成员的指针减去结构体指针,这个宏就是这样做的。而且由于编译器在计算时(编译时计算不是运行时计算,我已看过gcc的汇编代码)无需实际访问内存,所以该宏使用了地址0作为结构体的起始地址。实际上结构体地址可取不越界范围内的任意值,但是取0不会越界也省得再减去结构体的起始地址。解释一下宏定义:
0
内存地址
((structure *)0)
强制0为结构体起始地址
&(((structure *)0)->member)
取得结构体中member的地址
((int) &(((structure *)0)->member))
把member的地址转换为整数(因为结构体起始地址为0,所以没必要减去0)
这个宏很精巧,期待sizeof版。
|
|
|
----
|
|
[Original]
[Print]
[Top]
|
|
[Original]
[Print]
[Top]
|
我感觉sizeof不能做到。
也许某些特殊情况sizeof能够做到。
严重怀疑这道题的正确性。
|
|
|
----
I solemnly swear that I am up to no good
|
|
[Original]
[Print]
[Top]
|
|
[Original]
[Print]
[Top]
|
内核里双向链表的实现严重依赖这个功能
#define container_of(ptr, type, member) ({
const typeof( ((type *)0)->member ) *__mptr = (ptr);
(type *)( (char *)__mptr - offsetof(type,member) );})
|
|
|
----
|
|
[Original]
[Print]
[Top]
|
|
[Original]
[Print]
[Top]
|
内核里双向链表的实现严重依赖这个功能
#define container_of(ptr, type, member) ({
const typeof( ((type *)0)->member ) *__mptr = (ptr);
(type *)( (char *)__mptr - offsetof(type,member) );})
今天刚看到!!!
是不是这个意思
type是一个数据类型,它有一个成员叫member,
第一行的意思就是, 申请一个变量叫__mptr, 它的类型和结构type的成员member类型一样
__mptr 指向ptr, ptr是一个member的地址
通过offsetof获取到member成员在type结构中的偏移量,
然后将__mptr指针前移member在结构中的偏移量,就指向了包含ptr这个成员的结构地址
|
|
|
[Original]
[Print]
[Top]
|
|
|