请看一下这个宏。它在Symbian OS SDK中使用,该编译器基于GCC(< 4版本)。
#ifndef _FOFF
#if __GNUC__ < 4
#define _FOFF(c,f) (((TInt)&(((c *)0x1000)->f))-0x1000)
#else
#define _FOFF(c,f) __builtin_offsetof(c,f)
#endif
#endif
据我所知,它正在计算特定类/结构成员的偏移量。但我无法理解这个奇怪的陈述是如何工作的 - 什么是常数0x1000,为什么会出现?有人可以向我解释一下吗?
答案 0 :(得分:2)
Imo 0x1000只是一个随机选择的数字。它不是一个有效的指针,你可以使用零而不是它。
工作原理:
因为没有写入,没有accessViolation / segfault。
你可能使用零而不是0x1000并且丢弃减法(即只使用“((TInt)&amp;(((c *)0x0000) - &gt; f))”),但也许作者认为减去基数从指针到成员的指针比尝试直接将指针转换为整数更加“正确”。或者也许编译器提供可以具有负偏移的“隐藏”类成员(这在某些编译器中是可能的 - 例如Delphi编译器(我知道它不是c ++)提供了位于“self”之前的多个隐藏“字段”(模拟) “this”)指针),在这种情况下使用0x1000而不是0是有意义的。
答案 1 :(得分:1)
它正在计算'f'的相对地址作为地址0x1000的类/结构的成员,然后减去0x1000,以便只返回类/结构地址和成员函数地址之间的差异。我想一个非零值(即0x1000)用于避免空指针检测。
答案 2 :(得分:1)
“如果结构c
的成员完全从(完全对齐的;-)地址0x1000
开始,那么结构的成员f
会在哪个地址?” - 回答:您正在寻找的偏移量,当然减去结构的假设起始地址0x1000
...具有差异,AKA距离或偏移量,计算为整数,否则自动缩放地址算术扔掉你(演员)。
表达的哪些部分,特别是给你带来问题?
内部&(((c *)0x1000)->f)
是“位于f
的假设结构c
的成员0x1000
的地址。在它前面就是演员(我假设TInt
当然是某种整数类型,然后- 0x1000
获取偏移量(AKA距离或特定成员的地址与整个结构的开始之间的差异)。