2011-01-10 184 views
15

爲什麼下面的代碼有正確的輸出? int GGT沒有返回語句,但代碼仍然工作?沒有設置全局變量。函數返回值無返回語句

#include <stdio.h> 
#include <stdlib.h> 

int GGT(int, int); 

void main() { 
    int x1, x2; 
    printf("Bitte geben Sie zwei Zahlen ein: \n"); 
    scanf("%d", &x1); 
    scanf("%d", &x2); 
    printf("GGT ist: %d\n", GGT(x1, x2)); 
    system("Pause"); 
} 

int GGT(int x1, int x2) { 
    while(x1 != x2) { 
     if(x1 > x2) { 
      /*return*/ x1 = x1 - x2; 
     } 
     else { 
      /*return*/ x2 = x2 - x1; 
     } 
    } 
} 
+6

打開警戒線直到你的編譯器,你應該得到一個消息... – 2011-01-10 08:30:32

+0

我收到一條警告消息,但我interessted爲什麼它的工作,該編譯器設置了一個返回值,如果那裏沒人? – 2011-01-10 08:32:53

+1

[C函數定義爲int,但在主體中沒有return語句的可能重複仍然編譯](http://stackoverflow.com/questions/4260048/c-function-defined-as-int-but-having-no- return-statement-in-the-body-still-compi) – 2015-05-13 07:04:24

回答

27

對於x86至少,該函數的返回值應該是eax寄存器。任何在那裏的東西都會被認爲是來電者的返回值。

因爲eax被用作返回寄存器,所以它通常用作「臨時」寄存器,因爲它不需要保存。這意味着它很可能會被用作任何局部變量。因爲它們在最後都是相等的,所以正確的值更可能留在eax中。

11

它不應該工作,當然不上所有的編譯器和目標OS工作,即使它適用於你的。

可能的解釋是返回int的函數總是返回一些東西,而且通常是寄存器的內容。可能發生的情況是用於返回值的寄存器在您的情況下與用於在函數返回之前計算最後一個表達式的情況相同(在x86目標上,當然是eax)。

這就是說,一個優化編譯器檢測到沒有返回被允許完全刪除這個函數的代碼。從此以後,當激活更高的優化級別時,您看到的效果(可能會消失)。

我用gcc測試它:

GCC沒有優化: 輸入端10,20 - >結果是10個

GCC -O1 輸入端10,20 - >結果是1個

GCC -02 輸入10,20 - >結果是0

+1

可能downvoter解釋他相信或不喜歡什麼? – kriss 2011-01-10 09:03:23

-3

你不需要return語句,如果您正在使用指針。一般來說,你只能通過Return語句返回一個值,但是如果你使用指針,你可以返回你想要的數量。

的scanf( 「%d」,& X1);在那裏你給X1函數一個地址,而不是X1值。指針作品寬度的地址。你可以閱讀書籍,學習如何作品指針。

+0

不要這麼想,如果我使用指針 – 2011-01-10 08:37:06

3

在x86返回值被存儲在EAX寄存器,「不小心」也被該編譯器以存儲算術運算(或至少減法)的結果。你可以通過查看編譯器生成的程序集來檢查它。我同意克里斯 - 你不能認爲這將永遠是這種情況,所以最好明確指定返回值。

0

GCC糊劑「RET」指令在這種情況下,當在運行時鐺糊劑「UD2」和應用程序崩潰。