2009-06-01 27 views
17

मैं सी ++ में इनलाइन फ़ंक्शन कॉल का परीक्षण कर रहा हूं।सी ++ जीसीसी का उपयोग करते हुए इनलाइन फ़ंक्शन - कॉल क्यों?

Thread model: win32 
gcc version 4.3.3 (4.3.3-tdm-1 mingw32) 

सी ++ प्रोग्रामिंग भाषा wirtes में Stroustrup:

इनलाइन विनिर्देशक संकलक है कि यह कोड [...] इनलाइन उत्पन्न करने के लिए के बजाय के लिए कोड नीचे बिछाने का प्रयास करना चाहिए करने के लिए एक संकेत है एक बार समारोह और फिर सामान्य फ़ंक्शन कॉल तंत्र के माध्यम से कॉल करना।

हालांकि, मुझे पता चला है कि जेनरेट कोड बस इनलाइन नहीं है। isquare फ़ंक्शन के लिए संकेत है।

alt text http://i42.tinypic.com/8ys3f4.jpg

हो रहा क्यों है? मैं इनलाइन फ़ंक्शंस का उपयोग कैसे कर सकता हूं?

संपादित करें: आदेश पंक्ति विकल्प का प्रयोग किया:

**** Build of configuration Debug for project InlineCpp **** 

**** Internal Builder is used for build    **** 
g++ -O0 -g3 -Wall -c -fmessage-length=0 -osrc\InlineCpp.o ..\src\InlineCpp.cpp 
g++ -oInlineCpp.exe src\InlineCpp.o 
+1

क्या आपने ऑप्टिमाइज़ेशन स्तर पर जब कोड उत्पन्न किया है, तो क्या आपने जांच की है? साथ ही, कोड – Christoph

+2

संकलित करते समय '-फिनलाइन-फ़ंक्शंस' पैरामीटर जोड़ने का प्रयास करें, कृपया कोड को संकलित करने के लिए जीसीसी के साथ उपयोग की जाने वाली कमांड लाइन विकल्प पोस्ट करें। (यदि आप -ओ 3 या -फिनलाइन-फ़ंक्शंस का उपयोग नहीं कर रहे हैं तो "इनलाइन" को अनदेखा करते हुए जीसीसी मुझे आश्चर्य नहीं करता है)। – timday

+3

समस्या यह है कि -00 आप अपने कंपाइलर झंडे में हैं, इसका मतलब है ** नहीं ** अनुकूलन। इसे -O2 पर स्विच करें और इसे ठीक से रेखांकित किया जाएगा। –

उत्तर

22

कोई सामान्य सी ++ रास्ता इनलाइन कार्यों बनाने के लिए संकलक बल नहीं है। आपके द्वारा उद्धृत पाठ में 'संकेत' शब्द पर ध्यान दें - संकलक आपको सुनने के लिए बाध्य नहीं है।

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

संपादित करें: एनजेएसएफ उसकी प्रतिक्रिया में उचित जीसीसी कीवर्ड देता है।

0

चाहे इनलाइन को कंपाइलर पर रखा जाए। क्या यह इनलाइन संकेत को अनदेखा करने के लिए स्वतंत्र है। कुछ कंपाइलर्स में एक विशिष्ट कीवर्ड होता है (जैसे वीसी ++ में __forceinline) लेकिन वर्चुअल सदस्य फ़ंक्शंस के लिए ऐसे कीवर्ड वर्चुअल कॉल के साथ भी इनलाइन नहीं किया जाएगा।

3

यह एक संकेत है और शिकायत संकेत को अनदेखा करने का विकल्प चुन सकता है। मुझे लगता है कि मैंने कुछ पढ़ा है जहां जीसीसी आम तौर पर इसे अनदेखा करता है। मैं सुनता हूं कि वहां एक ध्वज था लेकिन यह अभी भी 100% मामलों में काम नहीं करता है। (मुझे अभी तक कोई लिंक नहीं मिला है)।

ध्वज: -ऑन ऑप्टिमाइज़ेशन स्तर पर फ़िनलाइन-फ़ंक्शंस चालू है।

+3

मेरा मानना ​​है कि मुख्य अंतर जीसीसी "इनलाइन" का भुगतान करता है, इसका मतलब है कि यह कार्य 600 निर्देशों तक बड़ा हो सकता है और अभी भी रेखांकित हो सकता है, जबकि फ़िनलाइन-फ़ंक्शंस के साथ ऑटो इनलाइनिंग के लिए विचार की गई इनलाइन की घोषणा 300 से कम नहीं होनी चाहिए निर्देश। आप इन सभी संख्याओं के साथ गड़बड़ कर सकते हैं और अधिकतर - अधिकतम-इनलाइन-इंन्स-ऑटो जैसे नामों को समायोजित करने के लिए - (लेकिन आपको एक बहुत अच्छा कारण चाहिए; डिफ़ॉल्ट ध्वनि हैं)। स्पष्ट और ऑटो इनलाइनिंग के लिए संख्याओं के बीच अंतर को बदलने का अर्थ है कि आप प्रभावी रूप से इनलाइन को प्रभाव में कम या ज्यादा प्रभाव डाल सकते हैं। – timday

+0

यह बहुत दिलचस्प है। धन्यवाद। –

47

माइकल कोहेन की तरह उल्लेख किया गया है, इनलाइन कीवर्ड हमेशा एक संकेत है, और आपके कार्य के मामले में जीसीसी ने इसे इनलाइन करने का फैसला नहीं किया है।

चूंकि आप जीसीसी का उपयोग कर रहे हैं, इसलिए आप __attribute ((always_inline) के साथ इनलाइन को मजबूर कर सकते हैं।

उदाहरण:

/* Prototype. */ 
inline void foo (const char) __attribute__((always_inline)); 

स्रोत: GCC inline docs

+0

gcc-fu –

+5

हाँ के लिए upvoted, लेकिन अगर प्रश्नकर्ता चला जाता है और __attribute __ ((always_inline) चिपकाना शुरू करता है); -ओ 3 के साथ संकलन करने के बजाय अपने सभी कार्यों पर, हम असफल हो गए हैं। – timday

+2

सहमत हुए। मुझे लगता है कि मैं अभी भी एक आशावादी हूं और मानता हूं कि ज्यादातर लोगों के पास कुछ सामान्य ज्ञान है ;-) – njsf

8

आप एक डीबग बिल्ड में देख रहे हैं (अनुकूलन अक्षम)? कंपाइलर्स आमतौर पर "डीबग" बिल्ड में इनलाइनिंग अक्षम करते हैं क्योंकि वे डिबगिंग को कड़ी मेहनत करते हैं।

किसी भी मामले में, inline निर्दिष्ट वास्तव में संकेत है। फ़ंक्शन को इनलाइन करने के लिए कंपाइलर की आवश्यकता नहीं है। क्यों किसी भी संकलक एक इनलाइन संकेत की अनदेखी करने का फैसला कर सकता कारणों की एक संख्या हैं: इनलाइन करने

  • एक संकलक एक आंतरिक एल्गोरिथ्म का उपयोग कर सकते क्या इनलाइन करने के लिए फैसला करने का समर्थन

    • एक संकलक सरल हो सकता है, और नहीं और संकेतों को अनदेखा करें।
    • एक संकलक का अपना शोध प्रणालियों का उपयोग कर सकते तय करने के लिए (कभी कभी, संकलक एक बेहतर काम की तुलना में आप संभवतः विशेष रूप से IA64 की तरह जटिल आर्किटेक्चर में, क्या इनलाइन के लिए चुनने पर क्या कर सकते हैं कर सकते हैं) कि संकेत, इनलाइन किए जाने वाले के बावजूद प्रदर्शन में सुधार नहीं होगा
  • 4

    इनलाइन संकलक को एक सुझाव से अधिक कुछ नहीं है कि, यदि इस फ़ंक्शन को इनलाइन करना संभव है तो संकलक को ऐसा करने पर विचार करना चाहिए। कुछ फ़ंक्शंस स्वचालित रूप से इनलाइन होंगे क्योंकि वे बहुत आसान हैं, और अन्य फ़ंक्शन जिन्हें आप सुझाव देते हैं यह इनलाइन करता है क्योंकि वे जटिल नहीं हैं।

    इसके अलावा, मैंने देखा कि आप एक डीबग बिल्ड कर रहे हैं। मुझे वास्तव में पता नहीं है, लेकिन यह संभव है कि संकलक डीबग बिल्ड के लिए इनलाइनिंग को अक्षम करता है क्योंकि यह डीबगर के लिए चीजों को मुश्किल बनाता है ...

    0

    मुझे इसी तरह की समस्याओं का सामना करना पड़ा और पाया कि यह केवल तभी काम करता है जब इनलाइन फ़ंक्शन लिखा गया हो एक हेडर फ़ाइल।

    +0

    डाउनवोट क्यों? sybreon सही है, इस मामले में कि रेखांकित समारोह किसी अन्य मॉड्यूल से कहा जाता है ... – bitsmack

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