0

私の知る限り、「offsetof」マクロは次のように定義されています。

#define offsetof(st, m) ((size_t)(&((st *)0)->m))

このリンクに基づいて: http://en.wikipedia.org/wiki/Offsetof

そこで、構造体メンバーのオフセットを計算する独自のコード スニペットを作成します。

typedef struct{
    char a;
    int b;
    int c;
}example_struct;

int main(int argc, char *argv[])
{
    example_struct *p = 0;

    printf("%p\n", &(p->a));        --> 00000000
    printf("%p\n", &(p->b));        --> 00000004
    printf("%p\n", &(p->c));        --> 00000008

    printf("%p\n", &(p->a));        --> 0
    printf("%p\n", &(p->b));        --> 4
    printf("%p\n", &(p->c));        --> 8

    cout << &(p->a);        --> this line cause crash ???
    cout << &(p->b);        --> 00000004
    cout << &(p->c);        --> 00000008

    cout << (unsigned int)&(p->a);        --> 0
    cout << (unsigned int)&(p->b);        --> 4
    cout << (unsigned int)&(p->c);        --> 8

    return 0;
}

私の質問は次のとおりです。

  • 型キャストはクラッシュを引き起こしますか。最初のメンバーのオフセットをカウントできないのに、printf はできるのはなぜですか?
  • なぜ型キャストする必要があるのでしょうか。それはしなければなりませんか?

どんな意見でも大歓迎です:)

4

1 に答える 1

0

私の知る限り、「offsetof」マクロは次のように定義されています...

そのように定義されているわけではありません。というように定義されることがあります。一般に、ポインタに対してポインタ算術を実行するNULLと、未定義の動作が発生しますが、C ライブラリがたまたまこれを行う場合、特定のシステムでは問題ないはずです。

ちなみに、これは OS X 10.9 でもクラッシュしますclang++。ただし、を使用してもクラッシュしませoffsetof。結論: 未定義の動作は未定義であり、実装の詳細は実装の詳細であり、それらに依存したり、それらについて仮定したりすることは想定されていません。

于 2014-04-18T09:47:47.643 に答える