請問全域變數.值會自己歸0的問題 |
答題得分者是:brook
|
Cafia
一般會員 ![]() ![]() 發表:6 回覆:12 積分:3 註冊:2003-03-17 發送簡訊給我 |
請教一下
我的project有兩個Form..分別由a.cpp及b.cpp控制
為了方便傳遞參數..我在a.h中宣告了一些全域變數及函數
並在a.cpp內完成函數的定義
但現在在b.cpp內要用這這些全域變數時
發現全都歸0了耶..
我檢查過確定中間沒有動到這些值啊..搞不懂耶~ 而且.我在b.cpp中include"a.h"..也在a.cpp中include"b.h"
編譯的時候都沒有錯誤和警告
但執行的時候..出現警告訊息..
所有的全域變數都分別在a.obj及b.obj中被定義了..
問題
1.為什麼全域變數在b.cpp中使用時都會變成0?
2.為什麼會有這樣的警告訊息?
|
brook
資深會員 ![]() ![]() ![]() ![]() ![]() 發表:57 回覆:323 積分:371 註冊:2002-07-12 發送簡訊給我 |
|
Cafia
一般會員 ![]() ![]() 發表:6 回覆:12 積分:3 註冊:2003-03-17 發送簡訊給我 |
|
miyu
中階會員 ![]() ![]() ![]() 發表:13 回覆:96 積分:91 註冊:2003-05-01 發送簡訊給我 |
引言:雖然已經結案了, 可是我還是有點疑惑要吐嘈. 原作者並沒有把他的Code List出來, 只說了他用了Global Value. 因此, 以這種描述, 有兩種可能的code. a.h, case 1 static int A; static int B; sttaic int C; a.h, case 2: int A; int B; int C; 但是, 因為你把變數宣告在 include file 裡. 要知道, # 開頭的 command 都會被 preprocessor 處理掉, 因此, 假設你寫的是: A.cpp: #include "a.h" int main(void) { ... return 0; } B.cpp: #include "a.h" void somefunc(void) { ... } 在 a.h case 1 裡, preprocessor 將會把程式展開像這樣: a.cpp: static int A; static int B; sttaic int C; int main(void) { ... return 0; } b.cpp: static int A; static int B; sttaic int C; void somefunc(void) { ... } 在 a.h case 2 裡, preprocessor 將會把程式展開像這樣: a.cpp: int A; int B; int C; int main(void) { ... return 0; } b.cpp: int A; int B; int C; void somefunc(void) { ... } 這兩個有什麼不一樣呢? 注意到那個 static 嗎? 根據C/C 語言規則, 定義為 static variable 的變數, 可視區域僅限於宣告區域, 但是存在的壽命卻相當於 external variable 變數. 如果我沒記錯的話, static 變數的記憶空間配置是在程式載入初始時期 (就是 main() 被執行之前), 而他的內含值設定則是在該敘述第一次被執行到的時候, 且, 也只會設這麼一次, 如果沒有指定特殊值, 則會被設定為零. 且這個記憶體將會保證在離開 main() 之前會一直都是存在的. 而另一種寫法叫作 external variable. 根據 C/C 語言規則, 凡是 external variable 變數, 其空間配置和內容初始化時期是在 main() 被執行前, 如果沒有指定特殊值, 則會被設定為零. 且這個記憶體將會保證在離開 main() 之前會一直都是存在的. 如果是 external variable, 則無論你宣告多少次, 都應該只會有一份實體存在. 換句話說, 你在 external variable 可視的領域內作了任何修改, 都應該反應到同一個記憶體空間才對. 但是正常來說, external variable 大都宣告在實作檔 (.c/.cpp) 中, 然後在 header file 中宣告 extern type var_name, 然後含入這個 headrer file, 以便讓 compiler 知道有這一個 external variable. 或是說讓這個 external variable 的視野擴張到這個實作檔裡. 如果說像 case 2 那樣寫, 沒有宣告 extern, 而是都宣告成 external variable 的話. 當編譯時期, compiler 只要看得到reference symbol 就好, 他才不管實際空間位置配置, 所有實作檔中, symbol 是否重覆等問題. (只要同一個實作檔中沒有衝突, compiler就不管) 前面說的問題是 linker 要去處理的. 因此, 理論上 case 2 的寫法, 應該會引發 link time error (或是 Warning, 這可能要看 error level 的設定, 或是 linker 的實作判定). 所以我直覺認為, 原作者應該是採用 case 1 的寫法才對. 因為 case 2 的作法, 如果沒有任何錯誤 (duplication symbol 一類的錯誤), 至少應該會有警告. 我實在不太相信 borland c 會這麼蠢, 連個警告都不給才是. (要是真的, 那我真的無話可說...) case 1 的寫法, 你每一個 golbal variable 事實上都是不同的實體, 所以compiler/linker都不會提出任何質疑. 不信的話你可以去dump symbol, 他們應該都會被冠上一些奇怪的前置名稱才對. (為了避免linker出來叫) 以上是我的質疑引言: 有可能a和b各別存了一份資料,編譯未必會有警告,因為可以設某些警告不顯示. 我宣告全域變數的處理方式 1.在.cpp int AA; float BB; 2.在.h extern int AA; extern float BB;所以就是說如果全域變數的宣告部分,不能被重複include到.. 我剛測了這個的作法..真的就OK了 非常感謝~~ |
dllee
站務副站長 ![]() ![]() ![]() ![]() ![]() ![]() 發表:321 回覆:2519 積分:1711 註冊:2002-04-15 發送簡訊給我 |
很好的質疑
------
http://www.ViewMove.com |
miyu
中階會員 ![]() ![]() ![]() 發表:13 回覆:96 積分:91 註冊:2003-05-01 發送簡訊給我 |
引言: 很好的質疑 |
dllee
站務副站長 ![]() ![]() ![]() ![]() ![]() ![]() 發表:321 回覆:2519 積分:1711 註冊:2002-04-15 發送簡訊給我 |
每個 Compiler 有每個 Compiler 的優點,當然也有其缺點,不然,就不會各自有各自的愛好者。很高興,您已找到 Delphi + VC 良好開發環境。
說真的 Delphi 是比 BCB 更寬鬆,不是嗎
------
http://www.ViewMove.com |
本站聲明 |
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。 2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。 3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇! |