/*
&((type *)0)->member: 把“0”強制轉化爲指針類型,則該指針一定指向“0”(數據段基址)。因爲指針是“type *”型的,
所以可取到以“0”爲基地址的一個type型變量member域的地址。那麼這個地址也就等於member域到結構體基地址的偏移字節數。
((type *)((char *)(ptr)-(unsigned long)(&((type *)0)->member))):
(char *)(ptr)使得指針的加減操作步長爲一字節,(unsigned long)(&((type *)0)->member)等於ptr指向的member到該member所在結構體基地址的偏移字節數。
二者一減便得出該結構體的地址,轉換爲 (type *)型的指針。 */
#include <iostream>
#include <typeinfo>
using namespace std;
struct list_head {
struct list_head *next;
struct list_head *prev;
};
#define list_entry(ptr, type, member) \
((type *)((char *)(ptr)-(unsigned long)(&((type *)0)->member)))
struct test_list
{
int testdata;
float testfloat;
struct list_head list;
};
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
struct test_list b;
b.testdata = 5;
b.testfloat = 11.2;
struct test_list *pos = list_entry(&(b.testdata),struct test_list,testdata);
cout << pos->testfloat << endl;
return a.exec();
}
list_entry剖析與驗證
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.