Re: [問題] ((TYPE *) 0)-> .... 代表的是??

看板C_and_CPP (C/C++)作者 (鬼翼&娃娃魚)時間15年前 (2010/07/20 01:27), 編輯推噓3(3012)
留言15則, 5人參與, 最新討論串2/2 (看更多)
※ 引述《leontsai (幻風)》之銘言: : 有沒有高手請教一下我的疑惑 : 感恩 : 這MACRO 最主要是要回傳This 指標的PRIVATE 資料 : 其中 : Record 為一指標 BBS_PROTOCOL * This : TYPE 為一結構 : Field 為結構TYPE 中一個 component : #define _CR(Record, TYPE, Field) \ : ((TYPE *) ( (CHAR8 *)(Record) - (CHAR8 *) &(((TYPE *) 0)->Field))) : 1.最不能理解的是 0 ((TYPE *) 0) 這結構0代表是神麼意思? : 2. &(((TYPE *) 0)->Field))) 轉型為 (CHAR8 *) ? 位址轉型為 指向 CHAR8 的指標 抱歉回了這麼久以前的文, 小弟最近在一個偶然的機會.... 又看到了這個三年前面試被問過的題目, 本想po文請教.... 沒想到板上已經有文章了, 那就回在同一個標題下面吧.... 憑印象記的macro, 加自己湊的範例, code不長直接貼吧@@" == #include <stdio.h> #include <stdlib.h> #define OFFSET(type, element) ( &(((type*)0)->element) ) typedef struct _TESTrec { int x, y; char str[10]; double z; int dummy[2]; } TEST; int main() { printf("sizeof(TEST) = 0x%08X\n", sizeof(TEST)); printf("offset of str = 0x%p\n", OFFSET(TEST, str)); printf("offset of z = 0x%p\n", OFFSET(TEST, z)); system("PAUSE"); return 0; } == 主要是OFFSET這個macro裡這段: ((type*)0)->element 以前老迷惑於"對0轉型成指標存取element為什麼不會access violation"?? 然後又取址, 或者像l大看到的組合了一堆奇怪的位址運算到底是算什麼?_? 剛剛憑印象生出上面的code以後, 大概有了如下的推論 OFFSET(TEST, str) 展開以後 ( &(((TEST*)0)->str) ) 如果把 0 (零) 假設當成TEST* O (大o) 來看好了.... 這段code可寫成 &(O->str), 如果O指到0x0010000.... 那麼O->str指0x00100008, O->z指0x00100018(有align) 接著如果O指到0x00000000呢??就跟macro一模一樣了.... 那麼O->str指0x00000008, O->z指0x00000018(有align) 所以OFFSET在上例算出0x00000008與0x00000018兩位址! 也就是說它只是拿來找element在type裡的offset而已Orz -- 藉這篇文悼念一下被&(type*)0->element嚇傻的日子-_-|| PS. 以上數值舉例是假設在sizeof(int)為32的環境下.... -- ※ 發信站: 批踢踢實業坊(ptt.cc) ◆ From: 220.132.174.98 ※ 編輯: VictorTom 來自: 220.132.174.98 (07/20 01:35)

07/20 01:47, , 1F
V大 拍拍~
07/20 01:47, 1F

07/20 11:09, , 2F
C Standard Library 有提供 offsetof marcro。
07/20 11:09, 2F

07/20 11:10, , 3F
07/20 11:10, 3F

07/20 11:18, , 4F
感謝樓上s大的文章....<(_ _)>
07/20 11:18, 4F

07/20 11:28, , 5F
也推一下 #18xm_p1G g大寫的解釋....:)
07/20 11:28, 5F

07/20 14:37, , 6F
我有疑問,關於g大的return &(ptr->c) 為什麼不會有問題
07/20 14:37, 6F

07/20 14:37, , 7F
ptr不是擺明指向NULL了嗎?這樣return &(ptr->c)的位址
07/20 14:37, 7F

07/20 14:38, , 8F
不會有問題產生嗎...?
07/20 14:38, 8F

07/20 14:39, , 9F
呃抱歉,我沒注意到V大也有解釋
07/20 14:39, 9F

07/20 15:36, , 10F
這個 code 之所以能動作是因為標準賦予 & 了特殊的規則。
07/20 15:36, 10F

07/20 15:36, , 11F
所以把那一行拆成兩行寫雖然看似等價,但拆開會死。
07/20 15:36, 11F

07/20 15:39, , 12F
不過,好像也沒有拆開寫的方法就是了...
07/20 15:39, 12F

07/20 15:43, , 13F
同樣的 &(((struct T *)0)[1]) 也是有保證不會真的去做
07/20 15:43, 13F

07/20 15:43, , 14F
dereference,會直接代換成加法運算。
07/20 15:43, 14F

07/20 16:59, , 15F
感謝t大的說明....<(_ _)>
07/20 16:59, 15F
文章代碼(AID): #1CH8iM8N (C_and_CPP)
討論串 (同標題文章)
文章代碼(AID): #1CH8iM8N (C_and_CPP)