全國最多中醫師線上諮詢網站-台灣中醫網
發文 回覆 瀏覽次數:4640
推到 Plurk!
推到 Facebook!

請問全域變數.值會自己歸0的問題

答題得分者是:brook
Cafia
一般會員


發表:6
回覆:12
積分:3
註冊:2003-03-17

發送簡訊給我
#1 引用回覆 回覆 發表時間:2003-04-24 15:42:20 IP:163.28.xxx.xxx 未訂閱
請教一下 我的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

發送簡訊給我
#2 引用回覆 回覆 發表時間:2003-04-24 16:35:08 IP:218.160.xxx.xxx 未訂閱
有可能a和b各別存了一份資料,編譯未必會有警告,因為可以設某些警告不顯示. 我宣告全域變數的處理方式 1.在.cpp int AA; float BB; 2.在.h extern int AA; extern float BB;
Cafia
一般會員


發表:6
回覆:12
積分:3
註冊:2003-03-17

發送簡訊給我
#3 引用回覆 回覆 發表時間:2003-04-24 17:07:03 IP:163.28.xxx.xxx 未訂閱
引言: 有可能a和b各別存了一份資料,編譯未必會有警告,因為可以設某些警告不顯示. 我宣告全域變數的處理方式 1.在.cpp int AA; float BB; 2.在.h extern int AA; extern float BB;
所以就是說如果全域變數的宣告部分,不能被重複include到.. 我剛測了這個的作法..真的就OK了 非常感謝~~
miyu
中階會員


發表:13
回覆:96
積分:91
註冊:2003-05-01

發送簡訊給我
#4 引用回覆 回覆 發表時間:2003-08-06 01:34:11 IP:61.219.xxx.xxx 未訂閱
引言:
引言: 有可能a和b各別存了一份資料,編譯未必會有警告,因為可以設某些警告不顯示. 我宣告全域變數的處理方式 1.在.cpp int AA; float BB; 2.在.h extern int AA; extern float BB;
所以就是說如果全域變數的宣告部分,不能被重複include到.. 我剛測了這個的作法..真的就OK了 非常感謝~~
雖然已經結案了, 可是我還是有點疑惑要吐嘈. 原作者並沒有把他的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出來叫) 以上是我的質疑
dllee
站務副站長


發表:321
回覆:2519
積分:1711
註冊:2002-04-15

發送簡訊給我
#5 引用回覆 回覆 發表時間:2003-08-06 08:39:13 IP:61.224.xxx.xxx 未訂閱
很好的質疑  最近常看到許多問題,提問者都沒有提供夠多的資料,或是有其他考量,只將部分訊息 > 我在一個專案中,的 class="code"> [Linker Warning] Public symbol '_abc' defined in both module C:\TEST\UNIT1.OBJ and C:\TEST\UNIT3.OBJ [Linker Warning] Public symbol '_abc' defined in both module C:\TEST\UNIT1.OBJ and C:\TEST\UNIT4.OBJ [Linker Warning] Public symbol '_abc' defined in both module C:\TEST\UNIT3.OBJ and C:\TEST\UNIT4.OBJ 只是,這樣的 Linker Warning 對於初學者來說,可能會『略過』,也許整個專案組譯下來有許多的 Warning 但只要執行檔有產出,對於初學者來說,也許就認為沒有問題了。其實,我倒是希望初學者能好好看一下這些警告訊息,如困警告訊息看不懂,可以提問呀。 以我寫的程式,也不百分之百沒有 Warning,只不過,每一個 Warning 我都知道是什麼 code 所造成,是否會對程式執行運作造成影響等等。 提供給初學者作為學習 BCB 的參考。 【註】 如果全部改成 static int abc; 則不會有任何的 Warning/Error Message。 因為,以我的認知 static 本來就是 local 的,只因為它放在整個 Unit 的 global 區,但它也只限此 Unit 使用,對於別的 Unit 有同樣的宣告並不會有任何影響。 身為程式設計師必需對程式負責,Compiler 只是輔助的工具而己! 沒空更新的網頁... http://dllee.ktop.com.tw C及指標教學,計算機概論,資訊管理導論... http://dllee.adsldns.org 介紹Shells,LiteStep,GeoShell.... 發表人 - dllee 於 2003/08/06 08:44:13
------
http://www.ViewMove.com
miyu
中階會員


發表:13
回覆:96
積分:91
註冊:2003-05-01

發送簡訊給我
#6 引用回覆 回覆 發表時間:2003-08-06 12:26:50 IP:211.75.xxx.xxx 未訂閱
引言: 很好的質疑 最近常看到許多問題,提問者都沒有提供夠多的資料,或是有其他考量,只將部分訊息 > < face="Verdana, Arial, Helvetica"> 還有一種更難聽的說法: 不知道問題在哪裡 ... 雖然這麼說很得罪人 XD
引言: 我在一個專案中,的 Unit1,Unit3,Unit4.cpp 都加入了相同的 int abc; 的整體變數,組譯的結果是會發 Linker Warning,我所使用的 BCB 其 Error/Warning 都採用預設值。
我還是覺得BCB在某些方面的策略過於寬鬆. 類似這種問題, 我很確定在gcc 2.95.4 (目前在用的版本), Visual Studio 6, 2002, 2003, By default Linker會直接吐一個error給你. 太寬鬆的策略對寫code的人並不是一種好事. 養成壞習慣以後很難改的 :X Well, 這是 BCB Linker 的策略問題... 反正基於某些理由, 我已經改用Delphi VC 了... 唉.
引言: 【註】 如果全部改成 static int abc; 則不會有任何的 Warning/Error Message。 因為,以我的認知 static 本來就是 local 的,只因為它放在整個 Unit 的 global 區,但它也只限此 Unit 使用,對於別的 Unit 有同樣的宣告並不會有任何影響。
C/C 的變數有所謂的領域視野. 或是反過來說, Compiler 是否可以找到它需要的 reference symbol. C/C 的變數也有所謂的生命週期, 另一種說法是, Compiler 為你所添加的 pseudo-code 該在什麼時候為這些變數alloc/release memory space及Init, 甚至是class的建構/解構時間點, 及順序問題. (請參考Modern C Design Ch.6 Implementing Singletons)
引言: 沒空更新的網頁... http://dllee.ktop.com.tw C及指標教學,計算機概論,資訊管理導論... http://dllee.adsldns.org 介紹Shells,LiteStep,GeoShell....
哼哼, 很久沒去玩LiteStep了... 唉. 發表人 - Miyu 於 2003/08/06 12:42:28
dllee
站務副站長


發表:321
回覆:2519
積分:1711
註冊:2002-04-15

發送簡訊給我
#7 引用回覆 回覆 發表時間:2003-08-07 09:10:14 IP:61.224.xxx.xxx 未訂閱
每個 Compiler 有每個 Compiler 的優點,當然也有其缺點,不然,就不會各自有各自的愛好者。很高興,您已找到 Delphi + VC 良好開發環境。 說真的 Delphi 是比 BCB 更寬鬆,不是嗎  我則是選用 > <>沒空更新的網頁... href="http://dllee.adsldns.org">http://dllee.adsldns.org 介紹Shells,LiteStep,GeoShell....
------
http://www.ViewMove.com
系統時間:2024-07-31 6:36:50
聯絡我們 | Delphi K.Top討論版
本站聲明
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。
2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。
3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇!