&((myStruct *)0)->x returns 成员 x 在 myStruct 类型中的偏移量如何计算?
How does &((myStruct *)0)->x returns the offset of member x in type myStruct?
typedef struct {
unsigned char y;
unsigned short int x;
} myStruct;
void main(void) {
unsigned char offset = &((myStruct *)0)->x;
printf("Offset=%d\n", offset);
}
使用这个神奇的宏表达式 &((myStruct*)0)->x
returns 成员 x
在 myStruct
中的偏移量!谁能帮我理解它是如何分配内存的?我 google 我发现创建了一个 myStruct
类型的指针并保存地址 0
然后它计算了成员 x
的地址,这将导致偏移值。我不明白指针如何指向地址 0
?编译器是如何做到的?地址 0
是在 运行 时间(在主堆栈函数中)加载的虚拟地址吗?提前致谢!
Can anyone help me understand how it is allocated memory?
未分配。没有占用内存,也没有指针在此处取消引用。
编译器只是计算成员x
的地址并将其转换为整数。
Unsigned char 不是一种很好的存储偏移量的类型。 C 对此有特殊的类型。它被称为ptrdiff_t
。
我宁愿
ptrdiff_t offset = (char *)&(((myStruct *)0)->x) - (char *)&((myStruct *)0);
或
#define MYOFFSET(st,n) ((char *)&(((st *)0)->x) - (char *)&((st *)0))
ptrdiff_t offset = MYOFFSET(myStruct, x);
在这种情况下没有分配内存,它只是一个虚构的构造。
当你说
(myStruct*)0
这会创建一个指向恰好位于零的对象的指针,顺便说一句,这并没有错,因为在许多体系结构中,零地址是 100% 有效的,并且通常是控制结构的所在地。
在 x86 上,“零页”描述如下:
https://www.kernel.org/doc/html/latest/x86/zero-page.html
所以“零地址”正好指向“文本模式或帧缓冲区信息(结构screen_info)”,可以在这里看到:
https://docs.huihoo.com/doxygen/linux/kernel/3.7/uapi_2linux_2screen__info_8h_source.html
言归正传,->x
表示成员的位置,然后是 &
,它采用该给定成员的地址,该地址应该恰好位于 [=13] =].
由于AddressOfObject
为零,则表达式正好等于成员的偏移量。
typedef struct {
unsigned char y;
unsigned short int x;
} myStruct;
void main(void) {
unsigned char offset = &((myStruct *)0)->x;
printf("Offset=%d\n", offset);
}
使用这个神奇的宏表达式 &((myStruct*)0)->x
returns 成员 x
在 myStruct
中的偏移量!谁能帮我理解它是如何分配内存的?我 google 我发现创建了一个 myStruct
类型的指针并保存地址 0
然后它计算了成员 x
的地址,这将导致偏移值。我不明白指针如何指向地址 0
?编译器是如何做到的?地址 0
是在 运行 时间(在主堆栈函数中)加载的虚拟地址吗?提前致谢!
Can anyone help me understand how it is allocated memory?
未分配。没有占用内存,也没有指针在此处取消引用。
编译器只是计算成员x
的地址并将其转换为整数。
Unsigned char 不是一种很好的存储偏移量的类型。 C 对此有特殊的类型。它被称为ptrdiff_t
。
我宁愿
ptrdiff_t offset = (char *)&(((myStruct *)0)->x) - (char *)&((myStruct *)0);
或
#define MYOFFSET(st,n) ((char *)&(((st *)0)->x) - (char *)&((st *)0))
ptrdiff_t offset = MYOFFSET(myStruct, x);
在这种情况下没有分配内存,它只是一个虚构的构造。
当你说
(myStruct*)0
这会创建一个指向恰好位于零的对象的指针,顺便说一句,这并没有错,因为在许多体系结构中,零地址是 100% 有效的,并且通常是控制结构的所在地。
在 x86 上,“零页”描述如下:
https://www.kernel.org/doc/html/latest/x86/zero-page.html
所以“零地址”正好指向“文本模式或帧缓冲区信息(结构screen_info)”,可以在这里看到:
https://docs.huihoo.com/doxygen/linux/kernel/3.7/uapi_2linux_2screen__info_8h_source.html
言归正传,->x
表示成员的位置,然后是 &
,它采用该给定成员的地址,该地址应该恰好位于 [=13] =].
由于AddressOfObject
为零,则表达式正好等于成员的偏移量。