4

私はc99を学んでおり、構造について読んだ後、Linuxカーネルコードで次のマクロを見つけました:

#define FIELD_SIZEOF(t, f) (sizeof(((t*)0)->f))

私..何?使用法:

#include <stdio.h>
#define FIELD_SIZEOF(t, f) (sizeof(((t*)0)->f))

struct book {
    char title[100];
    char author[100];
};

int main(void)
{
    printf("%lu\n", FIELD_SIZEOF(struct book, title)); // prints 100
}

これが展開です(gcc -E)

printf("%lu\n", (sizeof(((struct book*)0)->title)));

私を本当に困惑させるのは0. 12+1-1+999および'a'に置き換えましたが"hello"常に機能します。

ソースにコメントはありません。ポインターを介して構造体メンバーにアクセスするために使用されることは知ってい->ますが、どのよう((struct book*)0)にポインターになることができますか? マクロはどのように機能しますか?

4

2 に答える 2

6

ここで重要なのはsizeof、コンパイル時にコンパイラによって計算されることです。したがって、指定したポインターが実際に逆参照されることはありません。結局のところ、オブジェクトが配置されている場所によってサイズが変わることはありません。演算子は、そのsizeofオペランドを純粋に型に関して評価します。

したがって、使用するアドレスは実際には関係ありませんが、0( NULL) が一般的な選択です。

于 2013-10-17T19:05:44.773 に答える
2
sizeof(((t*)0)->f)

はその引数を評価しないように定義されているため機能sizeofします (VLA が関係する場合はいくつかの例外があります)。

于 2013-10-17T19:04:44.863 に答える