I'm learning c99 and after reading about structures I found the following macro in the Linux Kernel code:
#define FIELD_SIZEOF(t, f) (sizeof(((t*)0)->f))
I.. what? Usage:
#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
}
Here's the expansion (gcc -E)
printf("%lu\n", (sizeof(((struct book*)0)->title)));
What really baffles me is the 0
. I replaced it with 1
, 2
, +1
, -1
, +999
and 'a'
and "hello"
, and it always works.
There's no comment in the source. I know that ->
is used to access a struct member through a pointer, but how can ((struct book*)0)
be a pointer? How does the macro work?
The key here is that sizeof
is calculated by the compiler at compile time. So, the pointer you specify is never actually dereferenced. After all, where an object is located won't change its size. The sizeof
operator will evaluate its operand purely in terms of types.
So, the address you use is actually irrelevant, but 0
(NULL
) is a common choice.