C語言中結構體偏移量的計算

2021-08-15 15:08:09 字數 2331 閱讀 1817

一、先來一段理論知識

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

print

?#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

print

?#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語言中的指...