一、先來一段理論知識
ansi c標準允許任何值為0的常量被強制轉換成任何一種型別的指標,並且轉換結果是乙個null指標,因此((s*)0)的結果就是乙個型別為s*的null指標。如果利用這個null指標來訪問s的成員當然是非法的,但&(((s*)0)->m)的意圖並非想訪問s欄位內容,而僅僅是計算當結構體例項的首址為((s*)0)時m欄位的位址。聰明的編譯器根本就不生成訪問m的**,而僅僅是根據s的記憶體布局和結構體例項首址在編譯期計算這個(常量)位址,這樣就完全避免了通過null指標訪問記憶體的問題。
二、在實踐中檢驗理論
下面是我在window環境下vs2008編譯器下的記錄,
[cpp]view plain
copy
?#include
#include
using
namespace std;
typedef
struct iso_msg
iso_msg;
#define fld_sizeof(s, m) sizeof(((s *)0)->m)
//#define offsetof(s,m) (( (size_t) &( ( (s*)0 )->m )) - (size_t)((s*)0))
#define offsetof1(s,m) ( (size_t) &( ( (s*)0 )->m ))
int _tmain(int argc, _tchar* argv)
#include #include using namespace std;
typedef struct iso_msg
iso_msg;
#define fld_sizeof(s, m) sizeof(((s *)0)->m)
//#define offsetof(s,m) (( (size_t) &( ( (s*)0 )->m )) - (size_t)((s*)0))
#define offsetof1(s,m) ( (size_t) &( ( (s*)0 )->m ))
int _tmain(int argc, _tchar* argv)
在上例中,存在兩個巨集定義,fld_sizeof和offsetof;這兩個巨集定義乙個是計算結構成員變數位元組大小,乙個是計算偏移量,其中offsetof和offsetof1是等價的,
三、系統的offsetof定義
該巨集在linux核心**(版本2.6.22)中定義如下:
/* offset of member member in a struct of type type. */
#define offsetof(type, member) __builtin_offsetof (type, member)
在windows下,
[cpp]view plain
copy
?#ifdef _win64
#define offsetof(s,m) (size_t)( (ptrdiff_t)&reinterpret_cast((((s *)0)->m)) )
#else
#define offsetof(s,m) (size_t)&reinterpret_cast((((s *)0)->m))
#endif
#else
#ifdef _win64
#define offsetof(s,m) (size_t)( (ptrdiff_t)&(((s *)0)->m) )
#else
#define offsetof(s,m) (size_t)&(((s *)0)->m)
#endif
#ifdef _win64
#define offsetof(s,m) (size_t)( (ptrdiff_t)&reinterpret_cast((((s *)0)->m)) )
#else
#define offsetof(s,m) (size_t)&reinterpret_cast((((s *)0)->m))
#endif
#else
#ifdef _win64
#define offsetof(s,m) (size_t)( (ptrdiff_t)&(((s *)0)->m) )
#else
#define offsetof(s,m) (size_t)&(((s *)0)->m)
#endif
四、參考內容
這裡有非常詳細的說明,大家可以來這裡檢視。
計算結構體偏移量
如果能夠讓 unsigned long type 的值為0,即 type 0的時候,那麼offset的值就是簡單的 offset unsigned long type.c 如果說 type 0,那麼type.c就可以等價於 type t 0 c。但是這個語句是不能單獨存在的,因為對null指標訪問成...
C語言中的指標加減偏移量
首先看一段程式 輸出結果為 2,5 第乙個結果好說,a 1後指標指向了陣列中的 2 而第二個為什麼輸出 5 呢。原理是c語言中的指標加減後,會根據指標的型別採用不同的偏移量。比如,int a int b a 1 則 b a sizeof int char a char b a 1 則b a size...
C語言中的指標加減偏移量
首先看一段程式 cpp nogutter view plain copy include intmain int p int a 1 printf d,d n a 1 p 1 return 0 輸出結果為 第乙個結果好說,a 1後指標指向了陣列中的 2 而第二個為什麼輸出 5 呢。原理是c語言中的指...