offsetof宏的實現


1、c語言的結構體中,因為字節對齊的問題,導致成員地址並不能根據類型的大小進行計算。例如:

struct test {
    char ch;
    int a;
}
printf("test的大小=%d",sizeof(struct test));   //答案是8
/*注意下面第二個char *,必須是char型指針(和結構體第一個成員類型一致),
**因為你強制轉換的是一個地址,所以必須用指針類型。
**另外一個地址只有有了類型才可以進行加減運算,否在地址+1不知道要移動幾個字節。
*/
int *p=(int *)(char *)&test+1; //錯誤,因為char並不是占用1個字節,而是4個字節 int *p=(int *)(char *)%test+4; //正確

2、offsetof宏的實現如下:

#define offsetof(TYPE,MEMBER)   (size_t) &((TYPE *)0)->MEMBER)

哈哈,復雜吧,解釋一下:由於造成空洞的對齊動作是由編譯器負責完成的,這里有一個欺騙編譯器的指令:((TYPE *)0),

意思是定義一個指向TYPE類型的指針,且該指針值(也就是該type類型的地址)為0,當然這是不可能引用成功的,0地址早已

被操作系統保護起來了:),那么這么做意義何在?我們知道:當前地址-首地址=偏移量,如果首地址為0呢?當前地址是不是

就是偏移量了?呵呵,明白了吧,強制把0轉換為type類型的指針,並不是為了訪問0地址的值,而是為了從編譯器里套話(假設首地址

為0時,當前地址是多少?)。

最后要注意:因為我們得到的是一個地址,所以要設置為size_t類型,如果設為int類型,編譯器就要警告了,因為int和size_t的大小不相同。

最后以編譯器的警告信息作為本文章的結尾吧:

warning: cast from pointer to integer of different size [-Wpointer-to-int-cast]

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM