2012-12-12 41 views
-1

可能重複:
Why does this C code work?結構抵消宏觀

我看到定義計算結構偏移宏如下

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

但我不讓我們看看這個定義是如何工作的。它看起來像一個結構成員可以通過NULL指針訪問。任何人都可以詳細說明這個表達式的工作原理嗎?

+1

指針實際上沒有解除引用。 – cnicutar

回答

1

該表達式在編譯時被優化,導致程序中的編譯時偏移值。

編譯器看到一個常量指針(0),看到一個常量偏移量,並且僅應用constant folding,產生地址0 + offset(== offset),這正是我們所需要的。

這是有趣的,這是否工作沒有任何優化或一些基本的常數摺疊總是做。

P.S.更確切地說,這個優化被稱爲Scalar Replacement of Aggregates,正如雷牟所指出的那樣。

+0

謝謝您指出這是由於編譯器優化。然而,從我嘗試過的叮叮聲中,通過「Scalar Replacement of Aggregates」實際上將這個宏變成了一個常量。 –

+0

@LeiMou是的,它是這個優化的更準確的名稱。我剛剛在Coursera的「編譯器」中應用了我的知識,爲此行爲命名:) –

1

1)首先一個空指針類型的結構 'ST' 被創建:(ST *)0

2)接着的這種結構的元件被取: - >米

3 )下面的部件的地址是:&(...)

4)最後,將部件的地址被轉換爲一個大小叔類型:(爲size_t)(...)

的工作發生在第3步,因爲指針爲空(即地址== 0),則地址不在成員之中只是包含結構內的成員位置。