Re: [問題] 沒有return

看板C_and_CPP作者 (幽光)時間14年前 (2010/10/20 02:18), 編輯推噓6(6026)
留言32則, 11人參與, 最新討論串2/2 (看更多)
是的,gcc可以編過.我還幫你做了個實驗. 下面是程式碼: bigdick@bigdick:~/code$ cat no_return.c #include <stdio.h> #include <stdlib.h> int f1(int b) { int a; a = b + 3; } int main(void) { int x; printf("輸入一個數字: "); scanf("%d", &x); printf("執行結果為: %d\n",f1(x)); return 0; } *********************************************** bigdick@bigdick:~/code$ gcc -o no_return no_return.c <-- 編譯通過 bigdick@bigdick:~/code$ ./no_return <-- 執行看看 輸入一個數字: 12 執行結果為: 15 是的,的確在沒有return的情況下幫你回傳了a值. 接下來,我們把程式碼再改一點地方再次編譯: bigdick@bigdick:~/code$ cat no_return.c #include <stdio.h> #include <stdlib.h> int f1(int b) { int a, c; <--這邊我增加了區域變數c a = b + 3; c = b; <--單純把參數b的值複製給c } int main(void) { int x; printf("輸入一個數字: "); scanf("%d", &x); printf("執行結果為: %d\n",f1(x)); return 0; } ********************************************** 再次編譯跟執行: bigdick@bigdick:~/code$ gcc -o no_return no_return.c <--編譯OK bigdick@bigdick:~/code$ ./no_return <--執行看看 輸入一個數字: 12 執行結果為: 12 大家看到這邊應該有猜出來, gcc當你指定回傳型態時,若你沒有return, 它會自己幫你挑出一個回傳, 而那個回傳值就是你動到的最後一個區域變數. 有人說VC不行,所以你的問題就只是編譯器造成的結果罷了(Dev-C採用gcc作編譯器). 也沒有什麼為什麼,人家編譯器就是設計成這樣,希望這樣有滿足到你的求知慾. -- ※ 發信站: 批踢踢實業坊(ptt.cc) ◆ From: 118.161.188.88

10/20 02:19, , 1F
所以你的正確結果是你瞎ㄇㄥ中的.
10/20 02:19, 1F

10/20 02:27, , 2F
感謝測試
10/20 02:27, 2F

10/20 02:31, , 3F
好像也不是完全這樣
10/20 02:31, 3F

10/20 02:31, , 4F
你把 c = b; 改成 c = 99;
10/20 02:31, 4F

10/20 02:32, , 5F
回傳值不會是99
10/20 02:32, 5F

10/20 02:33, , 6F
題外話:perl 就是把最後一個 statement 結果當回傳值 XD
10/20 02:33, 6F

10/20 02:34, , 7F
在原本那篇有人以組語的觀點解釋,我想是比較合理的,最終這
10/20 02:34, 7F

10/20 02:34, , 8F
本來就不是C應有的寫法,我們試圖去預測他的動作原理可能會
10/20 02:34, 8F

10/20 02:35, , 9F
造成難以規範的動作出現.
10/20 02:35, 9F

10/20 09:13, , 10F
驚!不是這樣吧... 只是因為EAX裡的殘值被當成回傳值而已
10/20 09:13, 10F

10/20 09:14, , 11F
不同編譯器出來結果不同,是因為不同編譯器對register的
10/20 09:14, 11F

10/20 09:14, , 12F
操作不相同,會有這種結果只是運氣好EAX剛好在運算過程中
10/20 09:14, 12F

10/20 09:14, , 13F
被編譯器拿去用來暫存計算值
10/20 09:14, 13F

10/20 09:49, , 14F
這種東西別測了 最佳化開下去f1就剩return...
10/20 09:49, 14F

10/20 10:10, , 15F
樓上太直接了 XD
10/20 10:10, 15F

10/20 10:34, , 16F
這東西跟 calling convention 有關,x86 就剛好是 EAX。
10/20 10:34, 16F

10/20 10:35, , 17F
呼叫端才不管你有沒有實際傳回什麼,按照約定,它就是根據
10/20 10:35, 17F

10/20 10:35, , 18F
data type 去 register 裡,或把 register 的值當 pointer
10/20 10:35, 18F

10/20 10:36, , 19F
去 memory 取值。被呼叫端沒放,那是它違約 XD
10/20 10:36, 19F

10/20 10:37, , 20F
說起來這個東西還是個年經文,以前也有人問過,也有人做了
10/20 10:37, 20F

10/20 10:38, , 21F
跟你一樣的實驗,做出了和你一樣的結論。
10/20 10:38, 21F

10/20 10:38, , 22F
「它會自己幫你挑出一個回傳」<-- 實際上根本沒挑。
10/20 10:38, 22F

10/20 10:39, , 23F
而是一切隨緣。
10/20 10:39, 23F

10/20 10:45, , 24F
同意t大。補充一下,return 是 double 的話,值是存在st0
10/20 10:45, 24F

10/20 11:00, , 25F
不過C編譯器不會抓到樣的錯誤呀?
10/20 11:00, 25F

10/20 11:22, , 26F
@james732: gcc -Wall 的話會有警告訊息
10/20 11:22, 26F

10/20 23:00, , 27F
小弟幾個星期前剛好讀到C語言的spec...裡面有特別提到這件事
10/20 23:00, 27F

10/20 23:00, , 28F
它說 如果function沒有return 那是undefined behavior...
10/20 23:00, 28F

10/20 23:03, , 29F
10/20 23:03, 29F

10/21 00:19, , 30F
我有用arm編出原PO的程式,http://nopaste.csie.org/4962
10/21 00:19, 30F

10/21 00:19, , 31F
10/21 00:19, 31F

10/21 00:30, , 32F
看了好久...x86的組語實在是很沒感覺..orz
10/21 00:30, 32F
文章代碼(AID): #1ClU3fYf (C_and_CPP)
討論串 (同標題文章)
文章代碼(AID): #1ClU3fYf (C_and_CPP)