2013-10-17 68 views
2

我學習C99和閱讀結構之後,我發現在Linux Kernel code下面的宏:Linux內核FIELD_SIZEOF宏解釋

#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)怎樣才能成爲一個指針?宏如何工作?

+1

它與標準的'offsetof'宏的常見實現類似,儘管這一點有點棘手。 –

回答

4

這裏的關鍵是sizeof是由編譯器在編譯時計算的。所以,你指定的指針永遠不會被解除引用。畢竟,對象所在的位置不會改變其大小。運算符將純粹根據類型來評估其操作數。

因此,您使用的地址實際上是不相關的,但0NULL)是常見的選擇。

+0

更確切地說,sizeof * *的操作數不被計算*(除非它是可變長度數組類型,這裏不適用)。 –

+0

爲什麼'(t *)0'中有括號?如果我說得對,這不等於't * 0'嗎? – light2yellow

+1

@ light2yellow:這裏't'是結構體類型,因此'(t *)'是類型轉換爲't *'的類型。 – FatalError

2
sizeof(((t*)0)->f) 

作品,因爲sizeof被定義爲無法評估其參數(有一些例外,當VLA都參與)。