我正在学习c99,在阅读了结构后,我在Linux Kernel code中找到了以下宏:
#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
。我将其替换为1
,2
,+1
,-1
,+999
和'a'
以及"hello"
和它始终有效。
消息来源没有评论。我知道->
用于通过指针访问struct成员,但((struct book*)0)
如何成为指针?宏如何运作?
答案 0 :(得分:4)
这里的关键是编译器在编译时计算sizeof
。因此,您指定的指针实际上从未被解除引用。毕竟,对象所在的位置不会改变其大小。 sizeof
运算符将纯粹根据类型计算其操作数。
因此,您使用的地址实际上无关紧要,但0
(NULL
)是一种常见的选择。
答案 1 :(得分:2)
sizeof(((t*)0)->f)
有效,因为sizeof
被定义为不评估其参数(当涉及VLA时有一些例外)。