2011-01-10 19 views
15

निम्न कोड का सही आउटपुट क्यों है? इंट जीजीटी के पास कोई रिटर्न स्टेटमेंट नहीं है, लेकिन कोड वैसे भी काम करता है? कोई वैश्विक चर सेट नहीं हैं।फ़ंक्शन वापसी के बिना फ़ंक्शन रिटर्न मूल्य

#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

अपने कंपाइलर पर चेतावनी स्तर को सीधे चालू करें, और आपको एक संदेश प्राप्त करना चाहिए ... –

+0

मुझे एक चेतावनी संदेश मिल रहा है, लेकिन मैं interessted हूँ क्यों यह काम करता है, क्या संकलक वापसी मूल्य सेट करता है, अगर कोई भी नहीं है? –

+1

[सी फ़ंक्शन को int के रूप में परिभाषित करने के संभावित डुप्लिकेट लेकिन शरीर में कोई रिटर्न स्टेटमेंट अभी भी संकलित नहीं है] (http://stackoverflow.com/questions/4260048/c-function-defined-as-int-but-having-no- रिटर्न-कथन-इन-द-बॉडी-स्टिल-कंपी) –

उत्तर

27

कम से कम x86 के लिए, इस फ़ंक्शन का वापसी मान eax रजिस्टर में होना चाहिए। वहां मौजूद कुछ भी कॉलर द्वारा वापसी मूल्य माना जाएगा।

क्योंकि eax का उपयोग रिटर्न रजिस्टर के रूप में किया जाता है, इसे अक्सर कैली द्वारा "स्क्रैच" रजिस्टर के रूप में उपयोग किया जाता है, क्योंकि इसे संरक्षित करने की आवश्यकता नहीं होती है। इसका मतलब है कि यह बहुत संभव है कि इसका उपयोग किसी भी स्थानीय चर के रूप में किया जाएगा। क्योंकि दोनों अंत में बराबर हैं, यह अधिक संभावना है कि सही मान eax में छोड़ा जाएगा।

+0

ईएक्स रजिस्टर कहां है ?? सीपीयू रजिस्टर ?? – Anjaneyulu

11

यह काम नहीं करना चाहिए और निश्चित रूप से सभी संकलनकर्ता और लक्ष्य ओएस पर काम नहीं करते, भले ही यह तुम्हारा पर काम करता है।

संभावित स्पष्टीकरण यह है कि एक फ़ंक्शन लौटने वाला फ़ंक्शन हमेशा कुछ लौटाता है, और यह आमतौर पर एक रजिस्टर की सामग्री है। ऐसा शायद होता है कि रिटर्न वैल्यू के लिए इस्तेमाल किया गया रजिस्टर आपके मामले में फ़ंक्शन से लौटने से पहले अंतिम अभिव्यक्ति की गणना करने के लिए उपयोग किया जाता है (x86 लक्ष्य पर, निश्चित रूप से eax)।

यह कहा जा रहा है कि एक अनुकूलन कंपाइलर यह पता लगा रहा है कि इस समारोह के कोड को पूरी तरह से हटाने की अनुमति नहीं है। अब उच्च प्रभाव अनुकूलन स्तर को सक्रिय करते समय आप देख सकते हैं कि प्रभाव गायब हो सकता है (मई)। > परिणाम 1

जीसीसी है - -> परिणाम 10

जीसीसी -O1 आदानों 10, 20 है आदानों 10, 20: अनुकूलन के बिना

जीसीसी:

मैं जीसीसी के साथ यह परीक्षण किया -ओ 2 इनपुट 10, 20 -> परिणाम 0

+1

मई डाउनवॉटर बताता है कि वह क्या मानता है या नापसंद करता है? – kriss

-3

यदि आप पॉइंटर्स का उपयोग कर रहे हैं तो आपको वापसी विवरण की आवश्यकता नहीं है। आम तौर पर, आप रिटर्न स्टेटमेंट द्वारा केवल एक मान वापस कर सकते हैं, लेकिन यदि आप पॉइंटर्स का उपयोग करते हैं तो आप कितने चाहें वापस कर सकते हैं।

स्कैनफ़ ("% d", & x1); वहां आप एक्स 1 के एड्रेस को काम नहीं करते हैं, एक्स 1 वैल्यू नहीं। पॉइंटर्स चौड़ाई के पते काम करता है। पॉइंटर्स को कैसे काम करना है, सीखने के लिए आप पुस्तकें पढ़ सकते हैं।

+0

ऐसा मत सोचो, चर के दायरे को भी सेट किया गया है यदि मैं पॉइंटर्स –

+1

के साथ काम करता हूं लेकिन इस सवाल के साथ कुछ भी नहीं है। –

+0

ओएच, क्षमा करें, क्षमा करें। मैंने सोचा था कि लिखा गया था। जीजीटी (और x1, और x2)) और int जीजीटी (int * x1, int * x2)। मैं कोड को अलग से नहीं पढ़ता, मैं न ही सही हूं, क्षमा करें। :) – VakhoQ

3

x86 पर वापसी मूल्य ईएक्स रजिस्टर में संग्रहीत किया जाता है, जो इस संकलक द्वारा अंकगणितीय परिचालन (या कम से कम घटाव) के परिणाम को संग्रहीत करने के लिए "गलती से" भी प्रयोग किया जाता है। आप इसे अपने कंपाइलर द्वारा उत्पन्न असेंबली को देखकर देख सकते हैं। मैं क्रिस से सहमत हूं - आप यह नहीं मान सकते कि यह हमेशा मामला होगा, इसलिए वापसी मूल्य स्पष्ट रूप से निर्दिष्ट करना बेहतर है।

+0

ऐसा मत सोचो कि यह हमेशा काम करेगा, लेकिन मुझे इसमें दिलचस्पी थी, यह इस मामले में क्यों काम करता है। आपके उत्तर के लिए धन्यवाद! –

0

जीसीसी इस तरह के मामले में "ret" निर्देश चिपकाता है, जबकि क्लैंग पेस्ट "ud2" और ऐप रन-टाइम पर दुर्घटनाग्रस्त हो जाता है।

संबंधित मुद्दे