線上訂房服務-台灣趴趴狗聯合訂房中心
發文 回覆 瀏覽次數:981
推到 Plurk!
推到 Facebook!

請問一下,為神麼我的程式有部份沒有辦法編譯到??

缺席
trilab
一般會員


發表:10
回覆:4
積分:2
註冊:2005-02-28

發送簡訊給我
#1 引用回覆 回覆 發表時間:2005-03-04 09:08:19 IP:140.118.xxx.xxx 未訂閱
請教各位前輩:     為甚麼我的副程式,有部份無法被編譯(紅色框框列),可是有的卻可以,而且還可以正常執行,可是沒有編譯的地方就被作是沒有的,還有我有把兩個副程式掉換位置也是一樣,可以的還是可以,不可以的還是不可以,我找了半天,找不到哪裡寫錯,請各位大大指導小弟我一下,感激不盡.
trilab
一般會員


發表:10
回覆:4
積分:2
註冊:2005-02-28

發送簡訊給我
#2 引用回覆 回覆 發表時間:2005-03-04 09:22:39 IP:140.118.xxx.xxx 未訂閱
我將上一個問題弄得清楚一點,我現在用了一個表單上面沒有任何東西,然後 我在程式裡面寫了一個副程式,可是副程式的部份都編譯不進去,請各位大大 幫忙一下,是我bcb掛了還是我寫錯了,謝謝.
trilab
一般會員


發表:10
回覆:4
積分:2
註冊:2005-02-28

發送簡訊給我
#3 引用回覆 回覆 發表時間:2005-03-04 09:30:56 IP:140.118.xxx.xxx 未訂閱
不好意思,是我疏忽了,忘記副程式要呼叫才會編譯,sorry
blk5743
高階會員


發表:34
回覆:371
積分:236
註冊:2003-11-17

發送簡訊給我
#4 引用回覆 回覆 發表時間:2005-03-04 09:32:35 IP:61.66.xxx.xxx 未訂閱
解釋你的圖二好了 因為你的test()根本沒用到(完全沒呼叫) 所以BCB沒必要編譯 你在TForm1::TForm1中,呼叫test() 你就會看到test()被編譯了 圖一的問題應該也是一樣
chtai
高階會員


發表:68
回覆:238
積分:116
註冊:2004-05-21

發送簡訊給我
#5 引用回覆 回覆 發表時間:2005-03-04 09:43:51 IP:59.105.xxx.xxx 未訂閱
另外給您一個建議, 程式碼請縮排  毫無惡意,不過講真的, 很難得看到有人寫程式不縮排的。 您不覺得沒縮排過的程式碼,看起來很痛苦嗎? --
------
My Web: http://nelson.csie.us
My Blog: http://blog.nelson.csie.us
暗黑破壞神
版主


發表:9
回覆:2301
積分:1627
註冊:2004-10-04

發送簡訊給我
#6 引用回覆 回覆 發表時間:2005-03-04 12:10:55 IP:221.169.xxx.xxx 未訂閱
引言: 解釋你的圖二好了 因為你的test()根本沒用到(完全沒呼叫) 所以BCB沒必要編譯 你在TForm1::TForm1中,呼叫test() 你就會看到test()被編譯了 圖一的問題應該也是一樣
是這樣嗎? 我記得有沒有編,不是看有沒有呼叫到喔。 而是以一個 C,C 檔為單位下去編的喔。 而不是說寫在同一個檔中。會有某個函數被編譯了。某函數沒被編譯喔。 ^_^ 如果有問題,我們可以再討論。
bestlong
站務副站長


發表:126
回覆:734
積分:512
註冊:2002-10-19

發送簡訊給我
#7 引用回覆 回覆 發表時間:2005-03-04 12:33:59 IP:211.22.xxx.xxx 未訂閱
這是專案環境設定的編譯最佳化問題,以 Delphi 來說在 Project > Options > Compiler 內的 Code generation 有一個 Optimization 項目。 預設新增專案都會啟動編譯最佳化,所以在編譯的時候會先做原始碼分析然後沒用到的部份就會在編譯的過程被忽略跳過。 我是雪龍
------
http://blog.bestlong.idv.tw/
http://www.bestlong.idv.tw/
http://delphi-ktop.bestlong.idv.tw/
暗黑破壞神
版主


發表:9
回覆:2301
積分:1627
註冊:2004-10-04

發送簡訊給我
#8 引用回覆 回覆 發表時間:2005-03-04 13:02:14 IP:221.169.xxx.xxx 未訂閱
我不這麼認為。 因為你要這樣玩。你怎麼寫 lib??? lib 就是給別的人用的。 自己根本就沒有呼叫到。 如果這樣玩。那問題就大了。 所以通常他們會以OBJ為單位。 一個OBJ為一個LINK的單位。 而不是看你程式有沒有呼叫到來看要不要編譯。
blk5743
高階會員


發表:34
回覆:371
積分:236
註冊:2003-11-17

發送簡訊給我
#9 引用回覆 回覆 發表時間:2005-03-04 13:22:25 IP:61.66.xxx.xxx 未訂閱
引言: 引言: -------------------------------------------------------------------------------- 解釋你的圖二好了 因為你的test()根本沒用到(完全沒呼叫) 所以BCB沒必要編譯 你在TForm1::TForm1中,呼叫test() 你就會看到test()被編譯了 圖一的問題應該也是一樣 -------------------------------------------------------------------------------- 是這樣嗎? 我記得有沒有編,不是看有沒有呼叫到喔。 而是以一個 C,C 檔為單位下去編的喔。 而不是說寫在同一個檔中。會有某個函數被編譯了。某函數沒被編譯喔。 ^_^ 如果有問題,我們可以再討論。
暗黑破壞神你好 我所說的是我看到的情況 例如trilab的圖二好了 如果沒有呼叫tests(),他就真的不會被編譯 我不清楚為什麼會這樣(我是用BCB6),但他真的發生了 或許是bestlong大大說的原因, 也或許暗黑破壞神大大你了解其中的原因,可以為我們說明一下
pwipwi
版主


發表:68
回覆:629
積分:349
註冊:2004-04-08

發送簡訊給我
#10 引用回覆 回覆 發表時間:2005-03-04 13:35:35 IP:211.76.xxx.xxx 未訂閱
引言: 這是專案環境設定的編譯最佳化問題,以 Delphi 來說在 Project > Options > Compiler 內的 Code generation 有一個 Optimization 項目。 預設新增專案都會啟動編譯最佳化,所以在編譯的時候會先做原始碼分析然後沒用到的部份就會在編譯的過程被忽略跳過。 我是雪龍
你把compiler和linker弄混了,兩個做的事情是不一樣的。 C 會有略過編譯的只有使用preprocessor時和面對未使用的template function。其他的function全部都會經過compile,最後才由linker做選擇。
pwipwi
版主


發表:68
回覆:629
積分:349
註冊:2004-04-08

發送簡訊給我
#11 引用回覆 回覆 發表時間:2005-03-04 13:43:12 IP:211.76.xxx.xxx 未訂閱
引言: 我所說的是我看到的情況 例如trilab的圖二好了 如果沒有呼叫tests(),他就真的不會被編譯 我不清楚為什麼會這樣(我是用BCB6),但他真的發生了
如果你要證明沒有經過編譯,可以在裡面寫錯誤的語法然後再compile。如果沒有出現compiler的error才可證明。(麻煩你實驗看看~) 另外上一篇中我回應:"沒用到的template function不會經過編釋"..這也不完全正確,沒用到的template function還是會經過最基本的語意編譯(不然怎麼知道這是一個template function?)
blk5743
高階會員


發表:34
回覆:371
積分:236
註冊:2003-11-17

發送簡訊給我
#12 引用回覆 回覆 發表時間:2005-03-04 14:29:16 IP:61.66.xxx.xxx 未訂閱
感謝pwipwi 應該是說不會出現可以設值中斷點的地方(根本沒執行) 而不是說沒有被編譯
暗黑破壞神
版主


發表:9
回覆:2301
積分:1627
註冊:2004-10-04

發送簡訊給我
#13 引用回覆 回覆 發表時間:2005-03-04 15:09:58 IP:221.169.xxx.xxx 未訂閱
唉。去把 compiler 的書全看一次。 不然把 compiler 跟 linker 出來所產生的 map or lst 去看一看一下吧。 就會知道了。
bestlong
站務副站長


發表:126
回覆:734
積分:512
註冊:2002-10-19

發送簡訊給我
#14 引用回覆 回覆 發表時間:2005-03-04 17:44:09 IP:211.22.xxx.xxx 未訂閱
謝謝您的回應,而且是趨向於程式專業的解釋,也讓我驚覺到自己在友善的 Delphi IDE 介面下開發程式太久,脫離 C 的領域更久,許多較為深入或者是很基本的知識都歸還給了書本。    會回覆前述編譯最佳化的解答,是以撰寫應用程式的專案程式架構下來考量,且所寫的副程式在程式中有呼叫,我曾經碰到一個副程式改了老半天執行的結果一直都沒有改變,都是固定呈現某次編譯的執行結果。也找了 Bug 數天才發現原來這個副程式都沒有執行到。因為編譯檔(Delphi 下為 DCU)更本就沒有編繹出新的。所以我認為該副程式在編譯期間被最佳化演算法給判定是沒有需要的部份。不過很可惜當初的程式碼沒有刻意的保存起來,不過可以很確定的就是當我把 Optimization 選項關掉後,每次更改都有將 DCU 檔編譯出新的。我是以這樣的狀況來回答問題的。    再來上述所說的副程式,嚴格的來說是一個類別的私有成員函數所以會產生這樣的狀況,而以 lib 來談因為是屬於公用函數,就正如您所說的會編譯成 OBJ 檔。    
引言: 我不這麼認為。 因為你要這樣玩。你怎麼寫 lib??? lib 就是給別的人用的。 自己根本就沒有呼叫到。 如果這樣玩。那問題就大了。 所以通常他們會以OBJ為單位。 一個OBJ為一個LINK的單位。 而不是看你程式有沒有呼叫到來看要不要編譯。
我是雪龍 學海無涯覺無盡,勤做筆記防失憶
------
http://blog.bestlong.idv.tw/
http://www.bestlong.idv.tw/
http://delphi-ktop.bestlong.idv.tw/
暗黑破壞神
版主


發表:9
回覆:2301
積分:1627
註冊:2004-10-04

發送簡訊給我
#15 引用回覆 回覆 發表時間:2005-03-04 19:38:44 IP:221.169.xxx.xxx 未訂閱
引言: 再來上述所說的副程式,嚴格的來說是一個類別的私有成員函數所以會產生這樣的狀況,
不好意思。得修正一些觀念。 私有成員。就算沒呼叫到。它還是會編譯的。 你所遇到的問題。也許是你選擇了 release version 所造成的。 可是。那也不是沒編譯。而是在編譯時。把 DEBUG 用的一些對應資料都幹掉。 不留在EXE檔裏面。(PS。是不是留在EXE檔中。各種編譯器有不同的做法。) 你所謂的私有函數。其實。在編譯時,都會編。我在猜你是把編譯跟連結的觀念搞錯了。 編譯是都要編。可是連結時,是以一個OBJ為單位,把它”包”進EXE檔的。 這個部份,你可以看一下它所產生的MAP檔。 (PS。太多沒去看那些了。現在都玩GCC比較多)。 另,有個小工具可以讓你知道更清楚。TDUMP 你可以用它 tdump file.obj 去看看那個OBJ檔中,到底有些什麼東東。然後它的分配是怎樣。 之後比對你的程式碼。 這樣,你可以更了解編譯器為你做了些什麼了。^_^ 唉。在一個結案的文章中講這麼多。有人會看嗎?@.@
bestlong
站務副站長


發表:126
回覆:734
積分:512
註冊:2002-10-19

發送簡訊給我
#16 引用回覆 回覆 發表時間:2005-03-04 23:57:18 IP:218.162.xxx.xxx 未訂閱
是我不好意思才對 ^_^ 應該是我說的不夠有條理,您說的沒錯,全部的程式都是會經過編譯,只是編譯過程中有沒有透過最佳化演算法的處理。最佳化演算法會將部份程式碼給忽略掉,當然被忽略的程式部份一定是有其限制條件。    另外,也感謝您願意提供許多觀念與方向,至於已經結案這件事就隨風去吧,至少有留下一些知識與大家分享,不也是很好呢。    
引言: 私有成員。就算沒呼叫到。它還是會編譯的。 你所遇到的問題。也許是你選擇了 release version 所造成的。 可是。那也不是沒編譯。而是在編譯時。把 DEBUG 用的一些對應資料都幹掉。 不留在EXE檔裏面。(PS。是不是留在EXE檔中。各種編譯器有不同的做法。) 你所謂的私有函數。其實。在編譯時,都會編。我在猜你是把編譯跟連結的觀念搞錯了。 編譯是都要編。可是連結時,是以一個OBJ為單位,把它”包”進EXE檔的。 這個部份,你可以看一下它所產生的MAP檔。 (PS。太多沒去看那些了。現在都玩GCC比較多)。 另,有個小工具可以讓你知道更清楚。TDUMP 你可以用它 tdump file.obj 去看看那個OBJ檔中,到底有些什麼東東。然後它的分配是怎樣。 之後比對你的程式碼。 這樣,你可以更了解編譯器為你做了些什麼了。^_^ 唉。在一個結案的文章中講這麼多。有人會看嗎?@.@
我是雪龍 學海無涯覺無盡,勤做筆記防失憶
------
http://blog.bestlong.idv.tw/
http://www.bestlong.idv.tw/
http://delphi-ktop.bestlong.idv.tw/
暗黑破壞神
版主


發表:9
回覆:2301
積分:1627
註冊:2004-10-04

發送簡訊給我
#17 引用回覆 回覆 發表時間:2005-03-05 14:02:16 IP:59.104.xxx.xxx 未訂閱
對了。我又想起一件事情了。 你說你用 delphi 所以最佳化會做那樣的動作???? 這個我又想起當年 delphi 領域的一件”所謂的”大師(李X)說過。 delphi 當然比CBUILDER強啊。 因為它的編譯過程只要一次。 不像C要兩次。在開發速度比C快啊。 嗯。。。。。。所以。。。。所謂的最佳化是什麼呢? 是對程式碼一次一次的”VIEW”。 這個動作在當年做得最好的是 watcom C 而 DELPHI 做一次的編譯。因為它的語言定的比較嚴謹。 不像C可以做”不定參數”的用法。 所以在這個上面會比較快。可以省掉一次VIEW的動作。 可是。要說最佳化會省掉沒用到的碼。。。。。這個。真的是不可能啦。 因為。像我說的,你寫出的程式也許是LIB。也許是個 DLL,或是DCOM。COM。。。。之類的 SERVER。 在這支程式中沒被用到,可不代表不會被其它的CLIENT用到。 如果COMPILER會把它就幹掉。那不就是很大的問題嗎? ^_^
bestlong
站務副站長


發表:126
回覆:734
積分:512
註冊:2002-10-19

發送簡訊給我
#18 引用回覆 回覆 發表時間:2005-03-06 17:55:08 IP:211.20.xxx.xxx 未訂閱
首先,你可以先確認一下 C++ Built 的 Project Options 內是否也有一個 Optimization 的選項。    如果有(我想也應該會有),那就可以套入我所說的狀況。簡單的解釋好了。如果你寫了一個副程式大概如下:
function incOnce(v:Integer):Integer
var i:Integer;
begin
 i := v   1;
 Result := i;
end;
從這段程式來說,自 Begin 到 End 的範圍的所有 Code 都是必要的運算。但若是因為某個需要你將 Code 改成:
function incOnce(v:Integer):Integer
var i:Integer;
begin
 i := v   1;
// Result := i;
 Result := 100;
end;
這樣在 i := v 1 這一行的程式就沒有存在的必要,雖然這裡只有寫了一行程式,但如果是一個很複雜的程式會耗用很久的時間,因為再怎麼的運算都被最後推翻掉。這就是可以省略最佳化的區域,也可節省很多的運算時間。這樣的情節也可以擴大到整個被呼叫的副程式。 假如副程式得最短運算時間要 5 秒會傳回結果,但是承接的變數在整個程式當中都沒有被使用到,這樣在編譯的過程會在 Messages 視窗出現 XXXX never used 的訊息。而又剛好這段副程式只有這一行程式被呼叫。如果我現在是要產生出一個執行檔,那麼我可以認定這段副程式與呼叫副程式的那一行程式都是可以被忽略的。這樣有採用最佳化的編譯的執行檔與沒有採用最佳化的執行檔的執行時間就會有 5 秒的差異。 不知道這樣的解釋是否可以讓您有概念。
引言: 對了。我又想起一件事情了。 你說你用 delphi 所以最佳化會做那樣的動作???? 這個我又想起當年 delphi 領域的一件”所謂的”大師(李X)說過。 delphi 當然比CBUILDER強啊。 因為它的編譯過程只要一次。 不像C要兩次。在開發速度比C快啊。 嗯。。。。。。所以。。。。所謂的最佳化是什麼呢? 是對程式碼一次一次的”VIEW”。 這個動作在當年做得最好的是 watcom C 而 DELPHI 做一次的編譯。因為它的語言定的比較嚴謹。 不像C可以做”不定參數”的用法。 所以在這個上面會比較快。可以省掉一次VIEW的動作。 可是。要說最佳化會省掉沒用到的碼。。。。。這個。真的是不可能啦。 因為。像我說的,你寫出的程式也許是LIB。也許是個 DLL,或是DCOM。COM。。。。之類的 SERVER。 在這支程式中沒被用到,可不代表不會被其它的CLIENT用到。 如果COMPILER會把它就幹掉。那不就是很大的問題嗎? ^_^
我是雪龍 學海無涯覺無盡,勤做筆記防失憶
------
http://blog.bestlong.idv.tw/
http://www.bestlong.idv.tw/
http://delphi-ktop.bestlong.idv.tw/
暗黑破壞神
版主


發表:9
回覆:2301
積分:1627
註冊:2004-10-04

發送簡訊給我
#19 引用回覆 回覆 發表時間:2005-03-06 18:59:44 IP:203.69.xxx.xxx 未訂閱
唉。好吧。你要是認為你是對的。不接受我說的就算了。 你去把你的程式中加一行 int un_use_int; 在你的公域中。也就是不屬於任何函數的地方, 你看看你的最佳化會不會跟你說它不該出現。如你所說的會有這個訊息。
引言: 這樣在編譯的過程會在 Messages 視窗出現 XXXX never used 的訊息。
同理。你該把這樣的觀念擴大到一個函數。一個公用的函數。 自己再去看看書或是看看 tdump 出來的資料。再來看你的最佳化是不是會把沒用到的函數省略過。 就這樣。 再談下去無意義了。 自己去體會吧。
系統時間:2024-05-19 17:12:40
聯絡我們 | Delphi K.Top討論版
本站聲明
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。
2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。
3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇!