看板 C_and_CPP 關於我們 聯絡資訊
※ 引述《zlw (www.eJob.gov.tw)》之銘言: 我倒覺得這覺這會錯..其實是因為.... 這樣本來就寫錯了吧 orz 先考慮下這樣的定義 int a[2]={100,200}; int *p; 然後 p = a; 0x1000 ├─── │ a[0]=100 0x1004 ├─── │ a[1]=200 0x1008 ├─── │ p=0x1000 ├─── a本身代表 array a[] 所在的址, 所以 a[1] == *(a+1) == *(0x1000 + 1*sizeof(int)) == *(0x1004) 而因為 p=a; 所以 p[1] == *(p+1) == *(0x1000 + 1*sizeof(int)) == *(0x1004) 到這邊為止, 應該都是你也知道的東西 .___." 可是仔細看看你會發現.. 其實 p 本身是有塊 storage 去放他的, 也就是 p=0x1000 這個 value 是被存在 0x1008 這個位址.. 但 "a=0x1000" 這個 0x1000 本不會被存在哪裡呀.. 並不像 p 會被存下來一樣.. (這根function/method本身的address,也不會有塊storage去存他們是一樣的意思) 再回頭看來最一開始的問題就很清楚了, int a[2] = {100,200}; 和 extern int *a; int a[2] 表示有 define 兩塊 storage 去放 a[0] 和 a[1] 但 *a 卻是說, define 了一個 storage 去放一個pointer 在第一個 .c 裡會說, symbole a 的 address 在 0x1000 0x1000 ├─── 在第二個 .c 檔寫成 extern int *a; │a[0]=100 會變成說 a 這個用來放pointer的storage在 0x1000 0x1004 ├─── 而不是 a的內容是 0x1000 │a[1]=200 換個講法, 一個意思是 0x1008 ├─── a = 0x1000;, 這樣你才能 a[i] .. │ 另一個的意思 0x100C ├─── &a = 0x1000, │ 所以 a 的內容當然會變成 100 囉 > 利用 extern 可以對全域變數「重新宣告」資料型態一次。但怪就怪在 > 不能把全域變數 double a = 0; 重新宣告成 extern int a; (中略) > warning C4743: 'int * arr' 在 1.cpp 及 src.cpp 中有不同的大小: 8 和 4 位元組 > warning C4744: 'int * arr' 在 1.cpp 及 src.cpp' 中有不同的型別: 'array (8 > bytes)' 和 'pointer' 這個應該是 VC9 太聰明了, 還多去檢查這個 @.@a 一般來說, 應該是每個 .c(source) 自己是獨立編譯的, 編出來的 objects 檔再 link 起來.. link 恐怕只會看到symbole對應的address而不會看到size 用 gcc 在 command line 編就不會看到這種訊息了 @.@ -- 類似的惡搞法還有... 搾出 class method 的 address, 然後把他當 c function 呼叫...||| -- ※ 發信站: 批踢踢實業坊(ptt.cc) ◆ From: 140.112.41.173 ※ 編輯: cole945 來自: 140.112.41.173 (06/19 17:55) ※ 編輯: cole945 來自: 140.112.41.173 (06/19 17:55) ※ 編輯: cole945 來自: 140.112.41.173 (06/19 17:56)
zlw:謝謝。看到資料說,像這樣錯誤extern在規格中是「未定義行為」 06/19 18:09
zlw:所以沒有被阻擋這樣寫。可是如果1.cpp定義double a;則他在 06/19 18:09
zlw:symbol table會被裝飾名稱成?a@@3NA,而src.cpp裡extern int a 06/19 18:10
zlw:會被裝飾名稱成?a@@3HA,所以這種情況會連結錯誤。也只有在 06/19 18:11
zlw:陣列名稱跟指標時,才會名稱一致,然後就被騙的跑出錯誤指令 06/19 18:11
QQ29:推~ 可以請教一下 &p為什麼會是在0x1008呢 stack不是丟在上 06/19 18:21
QQ29:面嘛 0x1000-4之類的 06/19 18:21
zlw:只是舉例方便吧...不用太在意。push新資料後,ESP會變小沒錯 06/19 18:30
VictorTom:只是舉例方便吧?? 06/19 18:31
cole945:zlw說的對@_@ 我沒注意到是在討論C++. C++的話, 因為type 06/19 22:17
cole945:的問題, 直接link就錯誤了 @o@ 06/19 22:18
cole945:其實要嚴格講的話~ 也不是所有平台stack長的方向都一樣@.@ 06/19 22:19
cole945:往哪個方向長其實不用那麼在意囧" 06/19 22:19
cole945:剛研究了一下g++編出來的東西,好像只有function在mangling 06/19 22:27
cole945:所以不同type卻相同name的變數,也有可能發生link錯誤 @.@ 06/19 22:28