C++ 成员偏移量宏-需要详细信息

C++ 成员偏移量宏-需要详细信息,c++,gcc,symbian,C++,Gcc,Symbian,请看一下这个宏。它用于Symbian OS SDK,该编译器基于GCC(f是“位于0x1000的一个假设结构c的成员f的地址。它的正前方是cast(我假定TInt当然是某种整数类型),然后是-0x1000,以获得偏移量(也称为感兴趣的特定成员的地址与整个结构起点之间的距离或差异)。“如果有一个structc的成员正好从(完全对齐的;-)地址0x1000开始,那么该结构的成员f将位于哪个地址?“--回答:您要查找的偏移量,当然减去结构的假设起始地址0x1000,差即距离或偏移量,计算为整数,否则地

请看一下这个宏。它用于Symbian OS SDK,该编译器基于GCC(<4版本)

\ifndef\FOFF
#如果<4
#定义(c,f)((色调)和((c*)0x1000)-->f)-0x1000)
#否则
#定义(c,f)\内置偏移量(c,f)
#恩迪夫
#恩迪夫

我知道它正在计算特定类/结构成员的偏移量。但我无法理解这个奇怪的语句是如何工作的——常数0x1000是什么,为什么它会存在?有人能给我解释一下吗?

它计算出“f”作为地址0x1000处类/结构成员的相对地址,然后减去0x1000,这样只返回类/结构地址和成员函数地址之间的差。我设想使用一个非零值(即0x1000)来避免空指针检测。

它计算出地址0x1000处类/结构成员的相对地址“f”,然后减去0x1000,这样只返回类/结构地址和成员函数地址之间的差。我设想使用一个非零值(即0x1000)来避免空指针检测。

“如果有一个struct
c
的成员恰好从(完全对齐的;-)地址
0x1000
开始,那么该结构的成员
f
将位于哪个地址?”--回答:您要查找的偏移量,当然减去结构的假设起始地址
0x1000
。。。使用差值(也称为距离或偏移量)作为整数计算,否则地址算法中的自动缩放会将您抛出(从何处进行转换)

具体来说,表达的哪些部分给你带来了问题

内部部分
&((c*)0x1000)->f
是“位于
0x1000
的一个假设结构
c
的成员
f
的地址。它的正前方是cast(我假定
TInt
当然是某种整数类型),然后是
-0x1000
,以获得偏移量(也称为感兴趣的特定成员的地址与整个结构起点之间的距离或差异)。

“如果有一个struct
c
的成员正好从(完全对齐的;-)地址
0x1000
开始,那么该结构的成员
f
将位于哪个地址?“--回答:您要查找的偏移量,当然减去结构的假设起始地址
0x1000
,差即距离或偏移量,计算为整数,否则地址算法中的自动缩放会使您出错(从何处进行转换)

具体来说,表达的哪些部分给你带来了问题


内部部分
&((c*)0x1000)->f
是“位于
0x1000
的一个假设结构
c
的成员
f
的地址。它的正前方是cast(我假定
TInt
当然是某种整数类型),然后是
-0x1000
,以获得偏移量(也称为感兴趣的特定成员的地址与整个结构开头之间的距离或差)。

Imo 0x1000只是一个随机选择的数字。它不是有效的指针,您可以使用零来代替它

工作原理:

  • 将0x1000强制转换为类指针(类型为c的指针)。-(c*)0x1000
  • 获取指向类c-&((c*)0x1000)->f的“f”成员的指针
  • 将其转换为淡色。((淡色)和((c*)0x1000)->f)
  • 从指向c的成员的指针的整数值中减去指向基的指针的整数值(在本例中为0x1000):(((TInt)和((c*)0x1000)->f))-0x1000)
  • 由于没有写入f,因此不存在accessViolation/segfault


    您可能会使用零而不是0x1000并放弃减法(即只使用“((TInt)和((c*)0x0000)->f”)),但可能作者认为从指向成员的指针中减去基指针比尝试直接将指针转换为整数更“合适”的方法。或者编译器提供了“隐藏的”具有负偏移量的类成员(这在某些编译器中是可能的-例如Delphi编译器(我知道它不是c++)提供了位于“self”(类似于“this”)指针之前的多个隐藏“字段”),在这种情况下,使用0x1000而不是0是有意义的。

    Imo 0x1000只是一个随机选择的数字。它不是一个有效的指针,您可能会使用零来代替它

    工作原理:

  • 将0x1000强制转换为类指针(类型为c的指针)。-(c*)0x1000
  • 获取指向类c-&((c*)0x1000)->f的“f”成员的指针
  • 将其转换为淡色。((淡色)和((c*)0x1000)->f)
  • 从指向c的成员的指针的整数值中减去指向基的指针的整数值(在本例中为0x1000):(((TInt)和((c*)0x1000)->f))-0x1000)
  • 由于没有写入f,因此不存在accessViolation/segfault


    您可能会使用零而不是0x1000并放弃减法(即只使用“((TInt)和((c*)0x0000)->f”)),但可能作者认为从指向成员的指针中减去基指针比尝试直接将指针转换为整数更“合适”的方法。或者编译器提供了“隐藏”具有负偏移量的类成员(在某些编译器中是可能的-例如Delphi编译器(我知道它不是c++)提供了位于“self”(类似于“this”)指针之前的多个隐藏“field”),在这种情况下,使用0x1000而不是0是有意义的。

    谢谢,你的回答给了我足够的细节来理解这个宏。但是你能解释一下你在这句话中的意思吗:“否则地址算法中的自动缩放会使你感到困惑(从何处开始)。”基本上,关于自动缩放。@Haspem,例如,
    ((int*)0x1008)-(int*)0x1000)
    不是
    8
    ,而是
    8/sizeof(int)
    (f
    #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