इनलाइन फ़ंक्शन: Difference between revisions
No edit summary |
No edit summary |
||
Line 30: | Line 30: | ||
== मानक समर्थन == | == मानक समर्थन == | ||
सी ++ और [[C99|सी99]], लेकिन इसके पूर्ववर्ती के एंड आर सी और सी89 के पास इनलाइन फ़ंक्शंस के लिए समर्थन नहीं है, चूंकि भिन्न-भिन्न शब्दार्थ के | सी ++ और [[C99|सी99]], लेकिन इसके पूर्ववर्ती के एंड आर सी और सी89 के पास इनलाइन फ़ंक्शंस के लिए समर्थन नहीं है, चूंकि भिन्न-भिन्न शब्दार्थ के साथ, दोनों ही स्थितियों में, इनलाइन इनलाइनिंग को बाध्य नहीं करता है; संकलक यह चुनने के लिए स्वतंत्र है कि वह फ़ंक्शन को पूर्णतया भी इनलाइन न करे, या मात्र कुछ स्थितियों में, भिन्न-भिन्न संकलक इस बात में भिन्न होते हैं कि वे कितने जटिल फ़ंक्शन को इनलाइन में प्रबंधित कर सकते हैं। [[विजुअल सी प्लस प्लस|विजुअल सी++]], माइक्रोसॉफ्ट विज़ुअल सी++ और जीसीसी जैसे मुख्यधारा सी++ संकलक एक विकल्प का समर्थन करते हैं जो कंपाइलरों को किसी भी उपयुक्त फ़ंक्शन को स्वचालित रूप से इनलाइन करने देता है, यहां तक कि उन लोगों को भी इनलाइन फ़ंक्शन के रूप में चिह्नित नहीं किया जाता है। चूंकि, कंपाइलर को सभी इनलाइनिंग निर्णय लेने देने के लिए इनलाइन कीवर्ड को छोड़ना संभव नहीं है, क्योंकि लिंकर तब विभिन्न अनुवाद इकाइयों में डुप्लिकेट परिभाषाओं के बारे में शिकायत करेगा। ऐसा इसलिए है क्योंकि इनलाइन न मात्र कंपाइलर को संकेत देता है कि फ़ंक्शन को इनलाइन किया जाना चाहिए, अपितु इसका इस पर भी प्रभाव पड़ता है कि कंपाइलर फ़ंक्शन की कॉल करने योग्य आउट-ऑफ़-लाइन प्रतिलिपि उत्पन्न करेगा या नहीं (इनलाइन फ़ंक्शंस की स्टोरेज क्लास है)। | ||
== अमानक एक्सटेंशन == | == अमानक एक्सटेंशन == | ||
Line 73: | Line 73: | ||
यदि इनलाइन घोषणाओं को बाहरी इनलाइन घोषणाओं या अयोग्य घोषणाओं (सम्मलित, इनलाइन क्वालिफायर या स्टोरेज क्लास के बिना) के साथ मिश्रित किया जाता है, तो अनुवाद इकाई में एक परिभाषा होनी चाहिए (चाहे अयोग्य, इनलाइन या बाहरी इनलाइन हो) और एक बाहरी रूप से दृश्यमान फ़ंक्शन होगा इसके लिए उत्सर्जित किया जाता है। | यदि इनलाइन घोषणाओं को बाहरी इनलाइन घोषणाओं या अयोग्य घोषणाओं (सम्मलित, इनलाइन क्वालिफायर या स्टोरेज क्लास के बिना) के साथ मिश्रित किया जाता है, तो अनुवाद इकाई में एक परिभाषा होनी चाहिए (चाहे अयोग्य, इनलाइन या बाहरी इनलाइन हो) और एक बाहरी रूप से दृश्यमान फ़ंक्शन होगा इसके लिए उत्सर्जित किया जाता है। | ||
इनलाइन परिभाषित फ़ंक्शन के लिए प्रोग्राम में कहीं और उस नाम के साथ पूर्णतया एक फ़ंक्शन की आवश्यकता होती है जो या तो बाहरी इनलाइन या बिना क्वालीफायर के परिभाषित होता है। यदि पूरे प्रोग्राम में ऐसी एक से अधिक परिभाषाएँ प्रदान की गई हैं, तो लिंकर डुप्लिकेट प्रतीकों के बारे में शिकायत करेगा। यदि, चूंकि, इसकी कमी है, तो लिंकर आवश्यक रूप से शिकायत नहीं करता है, क्योंकि, यदि सभी उपयोगों को इनलाइन किया जा सकता है, तो इसकी आवश्यकता नहीं है। लेकिन यह शिकायत कर सकता है, क्योंकि कंपाइलर निरंतर इनलाइन क्वालीफायर को अनदेखा कर सकता है और इसके अतिरिक्त फ़ंक्शन पर कॉल उत्पन्न कर सकता है, जैसा कि सामान्यतः तब होता है जब कोड अनुकूलन के बिना संकलित किया जाता है। (यह वांछित व्यवहार हो सकता है, यदि फ़ंक्शन को सभी विधियों से हर जगह इनलाइन किया जाना चाहिए, और यदि ऐसा नहीं है तो एक त्रुटि उत्पन्न | इनलाइन परिभाषित फ़ंक्शन के लिए प्रोग्राम में कहीं और उस नाम के साथ पूर्णतया एक फ़ंक्शन की आवश्यकता होती है जो या तो बाहरी इनलाइन या बिना क्वालीफायर के परिभाषित होता है। यदि पूरे प्रोग्राम में ऐसी एक से अधिक परिभाषाएँ प्रदान की गई हैं, तो लिंकर डुप्लिकेट प्रतीकों के बारे में शिकायत करेगा। यदि, चूंकि, इसकी कमी है, तो लिंकर आवश्यक रूप से शिकायत नहीं करता है, क्योंकि, यदि सभी उपयोगों को इनलाइन किया जा सकता है, तो इसकी आवश्यकता नहीं है। लेकिन यह शिकायत कर सकता है, क्योंकि कंपाइलर निरंतर इनलाइन क्वालीफायर को अनदेखा कर सकता है और इसके अतिरिक्त फ़ंक्शन पर कॉल उत्पन्न कर सकता है, जैसा कि सामान्यतः तब होता है जब कोड अनुकूलन के बिना संकलित किया जाता है। (यह वांछित व्यवहार हो सकता है, यदि फ़ंक्शन को सभी विधियों से हर जगह इनलाइन किया जाना चाहिए, और यदि ऐसा नहीं है तो एक त्रुटि उत्पन्न होती है।) एक सुविधाजनक विधि हेडर फ़ाइलों में इनलाइन फ़ंक्शंस को परिभाषित करना और प्रति फ़ंक्शन एक .सी फ़ाइल बनाना है, जिसमें इसके लिए एक बाहरी इनलाइन घोषणा सम्मलित है और परिभाषा के साथ संबंधित हेडर फ़ाइल भी सम्मलित है। इससे कोई फर्क नहीं पड़ता कि घोषणा सम्मलित करने से पहले है या पश्चात में, | ||
यदि किसी फ़ंक्शन के सभी उपयोग इनलाइन थे, तो पहुंच योग्य कोड को अंतिम निष्पादन योग्य में जोड़े जाने से रोकने के लिए, यह सलाह दी जाती है<ref name="gcc-inline"/> कि ऐसी सभी .सी फ़ाइलों की ऑब्जेक्ट फ़ाइलों को एक एकल बाहरी इनलाइन फ़ंक्शन के साथ एक [[स्थिर लाइब्रेरी]] फ़ाइल में रखा जाए, सामान्यतः एआर आरसीएस के साथ, फिर भिन्न-भिन्न ऑब्जेक्ट फ़ाइलों के अतिरिक्त उस लाइब्रेरी से लिंक | यदि किसी फ़ंक्शन के सभी उपयोग इनलाइन थे, तो पहुंच योग्य कोड को अंतिम निष्पादन योग्य में जोड़े जाने से रोकने के लिए, यह सलाह दी जाती है<ref name="gcc-inline"/> कि ऐसी सभी .सी फ़ाइलों की ऑब्जेक्ट फ़ाइलों को एक एकल बाहरी इनलाइन फ़ंक्शन के साथ एक [[स्थिर लाइब्रेरी]] फ़ाइल में रखा जाए, सामान्यतः एआर आरसीएस के साथ, फिर भिन्न-भिन्न ऑब्जेक्ट फ़ाइलों के अतिरिक्त उस लाइब्रेरी से लिंक करें, इससे मात्र उन्हीं ऑब्जेक्ट फ़ाइलों को लिंक किया जा सकता है जिनकी वास्तव में आवश्यकता होती है, ऑब्जेक्ट फ़ाइलों को सीधे लिंक करने के विपरीत, जिसके कारण उन्हें निरंतर निष्पादन योग्य में सम्मलित किया जाता है। चूंकि, लाइब्रेरी फ़ाइल को लिंकर कमांड लाइन पर अन्य सभी ऑब्जेक्ट फ़ाइलों के पश्चात निर्दिष्ट किया जाना चाहिए, क्योंकि लाइब्रेरी फ़ाइल के पश्चात निर्दिष्ट ऑब्जेक्ट फ़ाइलों से फ़ंक्शंस की कॉल पर लिंकर द्वारा विचार नहीं किया जाएगा। इनलाइन फ़ंक्शंस से अन्य इनलाइन फ़ंक्शंस पर कॉल को लिंकर द्वारा स्वचालित रूप से हल किया जाएगा (एआर आरसीएस में एस विकल्प यह सुनिश्चित करता है)। | ||
एक वैकल्पिक समाधान लाइब्रेरी के अतिरिक्त लिंक टाइम ऑप्टिमाइज़ेशन का उपयोग करना है। जीसीसी उन अनुभागों को हटाने के लिए ध्वज -डब्ल्यूएल,--जीसी-सेक्शन प्रदान करता है जिनमें सभी फ़ंक्शन अप्रयुक्त हैं। एकल अप्रयुक्त बाहरी इनलाइन फ़ंक्शन के कोड वाली ऑब्जेक्ट फ़ाइलों के लिए यही स्थिति होगी। चूंकि, यह अन्य सभी ऑब्जेक्ट फ़ाइलों से सभी अप्रयुक्त अनुभागों को भी हटा देता है, न कि मात्र अप्रयुक्त बाहरी इनलाइन फ़ंक्शंस से संबंधित अनुभागों को। (फ़ंक्शंस को निष्पादन योग्य में लिंक करना वांछित हो सकता है जिन्हें प्रोग्रामर द्वारा प्रोग्राम के अतिरिक्त डिबगर से बुलाया जाना है, उदाहरण के लिए, प्रोग्राम की आंतरिक स्थिति की जांच करने के लिए।) इस दृष्टिकोण के साथ, यह भी संभव है प्रति फ़ंक्शन एक .सी फ़ाइल के अतिरिक्त सभी बाहरी इनलाइन फ़ंक्शंस के साथ एक .सी फ़ाइल का उपयोग करना। फिर फ़ाइल को -एफडेटा-सेक्शन -एफफंक्शन-सेक्शन के साथ संकलित करना होगा। चूंकि, जीसीसी मैनुअल पेज इसके बारे में चेतावनी देते हुए कहता है, "इन विकल्पों का उपयोग मात्र तभी करें जब ऐसा करने से महत्वपूर्ण लाभ होता है।" | एक वैकल्पिक समाधान लाइब्रेरी के अतिरिक्त लिंक टाइम ऑप्टिमाइज़ेशन का उपयोग करना है। जीसीसी उन अनुभागों को हटाने के लिए ध्वज -डब्ल्यूएल,--जीसी-सेक्शन प्रदान करता है जिनमें सभी फ़ंक्शन अप्रयुक्त हैं। एकल अप्रयुक्त बाहरी इनलाइन फ़ंक्शन के कोड वाली ऑब्जेक्ट फ़ाइलों के लिए यही स्थिति होगी। चूंकि, यह अन्य सभी ऑब्जेक्ट फ़ाइलों से सभी अप्रयुक्त अनुभागों को भी हटा देता है, न कि मात्र अप्रयुक्त बाहरी इनलाइन फ़ंक्शंस से संबंधित अनुभागों को। (फ़ंक्शंस को निष्पादन योग्य में लिंक करना वांछित हो सकता है जिन्हें प्रोग्रामर द्वारा प्रोग्राम के अतिरिक्त डिबगर से बुलाया जाना है, उदाहरण के लिए, प्रोग्राम की आंतरिक स्थिति की जांच करने के लिए।) इस दृष्टिकोण के साथ, यह भी संभव है प्रति फ़ंक्शन एक .सी फ़ाइल के अतिरिक्त सभी बाहरी इनलाइन फ़ंक्शंस के साथ एक .सी फ़ाइल का उपयोग करना। फिर फ़ाइल को -एफडेटा-सेक्शन -एफफंक्शन-सेक्शन के साथ संकलित करना होगा। चूंकि, जीसीसी मैनुअल पेज इसके बारे में चेतावनी देते हुए कहता है, "इन विकल्पों का उपयोग मात्र तभी करें जब ऐसा करने से महत्वपूर्ण लाभ होता है।" |
Revision as of 13:14, 9 July 2023
सी (प्रोग्रामिंग भाषा ) और सी ++ प्रोग्रामिंग भाषाओं में, एक इनलाइन फ़ंक्शन कीवर्ड (कंप्यूटर प्रोग्रामिंग) इनलाइन
के साथ योग्य है; यह दो उद्देश्यों को पूरा करता है:
- यह एक कंपाइलर निर्देश के रूप में कार्य करता है जो सुझाव देता है (लेकिन इसकी आवश्यकता नहीं है) कि कंपाइलर इनलाइन विस्तार करके फ़ंक्शन के बॉडी को इनलाइन प्रतिस्थापित करता है, अर्थात प्रत्येक फ़ंक्शन कॉल के पते पर फ़ंक्शन कोड डालकर, जिससे फ़ंक्शन कॉल के ओवरहेड को बचाया जा सकता है। इस संबंध में यह रजिस्टर
register
स्टोरेज क्लास निर्दिष्टकर्ता के अनुरूप है, जो इसी प्रकार एक अनुकूलन संकेत प्रदान करता है।[1] - इनलाइन का दूसरा उद्देश्य लिंकेज व्यवहार को बदलना है; इसका विवरण जटिल है। यह सी/सी++ भिन्न संकलन + लिंकेज नमूना के कारण आवश्यक है, विशेष रूप से क्योंकि फ़ंक्शन की परिभाषा (बॉडी) को उन सभी अनुवाद इकाई (प्रोग्रामिंग) में डुप्लिकेट किया जाना चाहिए जहां इसका उपयोग किया जाता है, जिससे की संकलन के समय इनलाइनिंग की अनुमति मिल सके, यदि फ़ंक्शन में बाहरी लिंकेज (सॉफ़्टवेयर) है, लिंकिंग के समय टकराव का कारण बनता है (यह बाहरी प्रतीकों की विशिष्टता का उल्लंघन करता है)। सी और सी ++ (और जीएनयू सी और विजुअल सी ++ जैसी बोलियां) इसे भिन्न-भिन्न विधियों से हल करती हैं।[1]
उदाहरण
एक इनलाइन फ़ंक्शन को सी या सी ++ में इस प्रकार लिखा जा सकता है:
inline void swap(int *m, int *n)
{
int tmp = *m;
*m = *n;
*n = tmp;
}
फिर, निम्नलिखित जैसा एक कथन है|
swap(&x, &y);
इसका अनुवाद किया जा सकता है (यदि कंपाइलर इनलाइनिंग करने का निर्णय लेता है, जिसके लिए सामान्यतः अनुकूलन को सक्षम करने की आवश्यकता होती है):
int tmp = x;
x = y;
y = tmp;
बहुत सारे स्वैप करते हुए सॉर्टिंग एल्गोरिदम लागू करते समय, यह निष्पादन गति को बढ़ा सकता है।
मानक समर्थन
सी ++ और सी99, लेकिन इसके पूर्ववर्ती के एंड आर सी और सी89 के पास इनलाइन फ़ंक्शंस के लिए समर्थन नहीं है, चूंकि भिन्न-भिन्न शब्दार्थ के साथ, दोनों ही स्थितियों में, इनलाइन इनलाइनिंग को बाध्य नहीं करता है; संकलक यह चुनने के लिए स्वतंत्र है कि वह फ़ंक्शन को पूर्णतया भी इनलाइन न करे, या मात्र कुछ स्थितियों में, भिन्न-भिन्न संकलक इस बात में भिन्न होते हैं कि वे कितने जटिल फ़ंक्शन को इनलाइन में प्रबंधित कर सकते हैं। विजुअल सी++, माइक्रोसॉफ्ट विज़ुअल सी++ और जीसीसी जैसे मुख्यधारा सी++ संकलक एक विकल्प का समर्थन करते हैं जो कंपाइलरों को किसी भी उपयुक्त फ़ंक्शन को स्वचालित रूप से इनलाइन करने देता है, यहां तक कि उन लोगों को भी इनलाइन फ़ंक्शन के रूप में चिह्नित नहीं किया जाता है। चूंकि, कंपाइलर को सभी इनलाइनिंग निर्णय लेने देने के लिए इनलाइन कीवर्ड को छोड़ना संभव नहीं है, क्योंकि लिंकर तब विभिन्न अनुवाद इकाइयों में डुप्लिकेट परिभाषाओं के बारे में शिकायत करेगा। ऐसा इसलिए है क्योंकि इनलाइन न मात्र कंपाइलर को संकेत देता है कि फ़ंक्शन को इनलाइन किया जाना चाहिए, अपितु इसका इस पर भी प्रभाव पड़ता है कि कंपाइलर फ़ंक्शन की कॉल करने योग्य आउट-ऑफ़-लाइन प्रतिलिपि उत्पन्न करेगा या नहीं (इनलाइन फ़ंक्शंस की स्टोरेज क्लास है)।
अमानक एक्सटेंशन
जीएनयू सी, बोली जीएनयू89 के भाग के रूप में, जो यह प्रदान करता है, सी89 के विस्तार के रूप में इनलाइन के लिए समर्थन है। चूंकि, शब्दार्थ सी ++ और सी99 दोनों से भिन्न है। सी90 मोड में आर्मसीसी एक गैर-मानक एक्सटेंशन के रूप में इनलाइन भी प्रदान करता है, जिसका शब्दार्थ जीएनयू89 और सी99 से भिन्न है।
कुछ कार्यान्वयन एक साधन प्रदान करते हैं जिसके द्वारा संकलक को किसी फ़ंक्शन को इनलाइन करने के लिए मजबूर किया जाता है, सामान्यतः पर कार्यान्वयन-विशिष्ट घोषणा विनिर्देशकों के माध्यम से:
- माइक्रोसॉफ्ट विज़ुअल सी ++:
__फ़ोर्सइनलाइन
- जीसीसी या क्लैंग: __एट्रिब्यूट__((हमेशा_इनलाइन)) या __एट्रिब्यूट__((__हमेशा_इनलाइन__)), जिनमें से पश्चात वाला निरंतर_इनलाइन नामक उपयोगकर्ता-परिभाषित मैक्रो के साथ टकराव से बचने के लिए उपयोगी है।
इसके अंधाधुंध उपयोग के परिणामस्वरूप बड़ा कोड (फूली हुई निष्पादन योग्य फ़ाइल), न्यूनतम या कोई प्रदर्शन लाभ नहीं हो सकता है, और कुछ स्थितियों में प्रदर्शन में हानि भी हो सकती है। इसके अतिरिक्त, कंपाइलर सभी परिस्थितियों में फ़ंक्शन को इनलाइन नहीं कर सकता, यदि इनलाइनिंग को मजबूर किया गया हो; इस स्थितियाँ में जीसीसी और विजुअल सी ++ दोनों चेतावनियाँ उत्पन्न करते हैं।
इनलाइनिंग को मजबूर करना उपयोगी है |
- कंपाइलर द्वारा इनलाइन का सम्मान नहीं किया जाता है (कंपाइलर लागत/लाभ विश्लेषक द्वारा अनदेखा किया जाता है), और
- इनलाइनिंग के परिणामस्वरूप आवश्यक प्रदर्शन में वृद्धि होती है
कोड पोर्टेबिलिटी के लिए, निम्नलिखित प्रीप्रोसेसर निर्देशों का उपयोग किया जा सकता है:
#ifdef _MSC_VER
#define forceinline __forceinline
#elif defined(__GNUC__)
#define forceinline inline __attribute__((__always_inline__))
#elif defined(__CLANG__)
#if __has_attribute(__always_inline__)
#define forceinline inline __attribute__((__always_inline__))
#else
#define forceinline inline
#endif
#else
#define forceinline inline
#endif
इनलाइन फ़ंक्शंस का संग्रहण वर्ग
स्टैटिक इनलाइन का सभी सी बोलियों और सी ++ में समान प्रभाव होता है। यदि आवश्यक हो तो यह स्थानीय रूप से दृश्यमान (आउट-ऑफ़-लाइन कॉपी) फ़ंक्शन का उत्सर्जन करता है।
स्टोरेज क्लास के अतिरिक्त, कंपाइलर इनलाइन क्वालीफायर को अनदेखा कर सकता है और सभी सी बोलीभाषाओं और सी++ में फ़ंक्शन कॉल उत्पन्न कर सकता है।
इनलाइन फ़ंक्शंस पर लागू या लागू नहीं होने पर स्टोरेज क्लास एक्सटर्न का प्रभाव सी बोलियों[2] और सी++ के बीच भिन्न होता है।[3]
सी 99
सी99 में, एक फ़ंक्शन परिभाषित इनलाइन कभी नहीं होगा, और एक फ़ंक्शन परिभाषित बाहरी इनलाइन निरंतर एक बाहरी रूप से दृश्यमान फ़ंक्शन उत्सर्जित करेगा। सी++ के विपरीत, अनुवाद इकाइयों के बीच साझा किए गए बाहरी रूप से दृश्यमान फ़ंक्शन को मात्र आवश्यकता पड़ने पर उत्सर्जित करने के लिए कहने का कोई विधि नहीं है।
यदि इनलाइन घोषणाओं को बाहरी इनलाइन घोषणाओं या अयोग्य घोषणाओं (सम्मलित, इनलाइन क्वालिफायर या स्टोरेज क्लास के बिना) के साथ मिश्रित किया जाता है, तो अनुवाद इकाई में एक परिभाषा होनी चाहिए (चाहे अयोग्य, इनलाइन या बाहरी इनलाइन हो) और एक बाहरी रूप से दृश्यमान फ़ंक्शन होगा इसके लिए उत्सर्जित किया जाता है।
इनलाइन परिभाषित फ़ंक्शन के लिए प्रोग्राम में कहीं और उस नाम के साथ पूर्णतया एक फ़ंक्शन की आवश्यकता होती है जो या तो बाहरी इनलाइन या बिना क्वालीफायर के परिभाषित होता है। यदि पूरे प्रोग्राम में ऐसी एक से अधिक परिभाषाएँ प्रदान की गई हैं, तो लिंकर डुप्लिकेट प्रतीकों के बारे में शिकायत करेगा। यदि, चूंकि, इसकी कमी है, तो लिंकर आवश्यक रूप से शिकायत नहीं करता है, क्योंकि, यदि सभी उपयोगों को इनलाइन किया जा सकता है, तो इसकी आवश्यकता नहीं है। लेकिन यह शिकायत कर सकता है, क्योंकि कंपाइलर निरंतर इनलाइन क्वालीफायर को अनदेखा कर सकता है और इसके अतिरिक्त फ़ंक्शन पर कॉल उत्पन्न कर सकता है, जैसा कि सामान्यतः तब होता है जब कोड अनुकूलन के बिना संकलित किया जाता है। (यह वांछित व्यवहार हो सकता है, यदि फ़ंक्शन को सभी विधियों से हर जगह इनलाइन किया जाना चाहिए, और यदि ऐसा नहीं है तो एक त्रुटि उत्पन्न होती है।) एक सुविधाजनक विधि हेडर फ़ाइलों में इनलाइन फ़ंक्शंस को परिभाषित करना और प्रति फ़ंक्शन एक .सी फ़ाइल बनाना है, जिसमें इसके लिए एक बाहरी इनलाइन घोषणा सम्मलित है और परिभाषा के साथ संबंधित हेडर फ़ाइल भी सम्मलित है। इससे कोई फर्क नहीं पड़ता कि घोषणा सम्मलित करने से पहले है या पश्चात में,
यदि किसी फ़ंक्शन के सभी उपयोग इनलाइन थे, तो पहुंच योग्य कोड को अंतिम निष्पादन योग्य में जोड़े जाने से रोकने के लिए, यह सलाह दी जाती है[3] कि ऐसी सभी .सी फ़ाइलों की ऑब्जेक्ट फ़ाइलों को एक एकल बाहरी इनलाइन फ़ंक्शन के साथ एक स्थिर लाइब्रेरी फ़ाइल में रखा जाए, सामान्यतः एआर आरसीएस के साथ, फिर भिन्न-भिन्न ऑब्जेक्ट फ़ाइलों के अतिरिक्त उस लाइब्रेरी से लिंक करें, इससे मात्र उन्हीं ऑब्जेक्ट फ़ाइलों को लिंक किया जा सकता है जिनकी वास्तव में आवश्यकता होती है, ऑब्जेक्ट फ़ाइलों को सीधे लिंक करने के विपरीत, जिसके कारण उन्हें निरंतर निष्पादन योग्य में सम्मलित किया जाता है। चूंकि, लाइब्रेरी फ़ाइल को लिंकर कमांड लाइन पर अन्य सभी ऑब्जेक्ट फ़ाइलों के पश्चात निर्दिष्ट किया जाना चाहिए, क्योंकि लाइब्रेरी फ़ाइल के पश्चात निर्दिष्ट ऑब्जेक्ट फ़ाइलों से फ़ंक्शंस की कॉल पर लिंकर द्वारा विचार नहीं किया जाएगा। इनलाइन फ़ंक्शंस से अन्य इनलाइन फ़ंक्शंस पर कॉल को लिंकर द्वारा स्वचालित रूप से हल किया जाएगा (एआर आरसीएस में एस विकल्प यह सुनिश्चित करता है)।
एक वैकल्पिक समाधान लाइब्रेरी के अतिरिक्त लिंक टाइम ऑप्टिमाइज़ेशन का उपयोग करना है। जीसीसी उन अनुभागों को हटाने के लिए ध्वज -डब्ल्यूएल,--जीसी-सेक्शन प्रदान करता है जिनमें सभी फ़ंक्शन अप्रयुक्त हैं। एकल अप्रयुक्त बाहरी इनलाइन फ़ंक्शन के कोड वाली ऑब्जेक्ट फ़ाइलों के लिए यही स्थिति होगी। चूंकि, यह अन्य सभी ऑब्जेक्ट फ़ाइलों से सभी अप्रयुक्त अनुभागों को भी हटा देता है, न कि मात्र अप्रयुक्त बाहरी इनलाइन फ़ंक्शंस से संबंधित अनुभागों को। (फ़ंक्शंस को निष्पादन योग्य में लिंक करना वांछित हो सकता है जिन्हें प्रोग्रामर द्वारा प्रोग्राम के अतिरिक्त डिबगर से बुलाया जाना है, उदाहरण के लिए, प्रोग्राम की आंतरिक स्थिति की जांच करने के लिए।) इस दृष्टिकोण के साथ, यह भी संभव है प्रति फ़ंक्शन एक .सी फ़ाइल के अतिरिक्त सभी बाहरी इनलाइन फ़ंक्शंस के साथ एक .सी फ़ाइल का उपयोग करना। फिर फ़ाइल को -एफडेटा-सेक्शन -एफफंक्शन-सेक्शन के साथ संकलित करना होगा। चूंकि, जीसीसी मैनुअल पेज इसके बारे में चेतावनी देते हुए कहता है, "इन विकल्पों का उपयोग मात्र तभी करें जब ऐसा करने से महत्वपूर्ण लाभ होता है।"
कुछ लोग पूरी तरह से भिन्न दृष्टिकोण की अनुशंसा करते हैं, जो हेडर फ़ाइलों में इनलाइन के अतिरिक्त फ़ंक्शंस को स्थिर इनलाइन के रूप में परिभाषित करना है।[2] फिर, कोई पहुंच योग्य कोड उत्पन्न नहीं होगा। चूंकि, विपरीत स्थिति में इस दृष्टिकोण में एक खामी है: यदि फ़ंक्शन को एक से अधिक अनुवाद इकाइयों में इनलाइन नहीं किया जा सका तो डुप्लिकेट कोड उत्पन्न किया जाएगा। उत्सर्जित फ़ंक्शन कोड को अनुवाद इकाइयों के बीच साझा नहीं किया जा सकता क्योंकि इसमें भिन्न-भिन्न पते होने चाहिए। यह एक और कमी है; हेडर फ़ाइल में स्टैटिक इनलाइन के रूप में परिभाषित ऐसे फ़ंक्शन का पता लेने से विभिन्न अनुवाद इकाइयों में भिन्न-भिन्न मान प्राप्त होंगे। इसलिए, स्थिर इनलाइन फ़ंक्शंस का उपयोग मात्र तभी किया जाना चाहिए जब उनका उपयोग मात्र एक अनुवाद इकाई में किया जाता है, जिसका अर्थ है कि उन्हें मात्र संबंधित .सी फ़ाइल में जाना चाहिए, हेडर फ़ाइल में नहीं किया जाता है।
जीएनयू89
इनलाइन और एक्सटर्न इनलाइन के जीएनयू89 शब्दार्थ अनिवार्य रूप से सी99 के पूर्णतया विपरीत हैं,[4] इस अपवाद के साथ कि जीएनयू89 एक बाहरी इनलाइन फ़ंक्शन को एक अयोग्य फ़ंक्शन के रूप में फिर से परिभाषित करने की अनुमति देता है, जबकि सी99 इनलाइन ऐसा नहीं करता है।[5] इस प्रकार, पुनर्परिभाषा के बिना जीएनयू89 एक्सटर्न इनलाइन सी99 इनलाइन की तरह है, और जीएनयू89 इनलाइन सी99 एक्सटर्न इनलाइन की तरह है; दूसरे शब्दों में, जीएनयू89 में, एक फ़ंक्शन परिभाषित इनलाइन निरंतर होगा और एक फ़ंक्शन परिभाषित बाहरी इनलाइन कभी भी बाहरी रूप से दृश्यमान फ़ंक्शन उत्सर्जित नहीं करेगा। इसके लिए तर्क यह है कि यह वेरिएबल्स से मेल खाता है, जिसके लिए भंडारण कभी भी आरक्षित नहीं होगा यदि इसे बाहरी के रूप में परिभाषित किया गया है और निरंतर यदि इसके बिना परिभाषित किया गया है। इसके विपरीत, सी99 के लिए तर्क यह है कि यह आश्चर्यजनक होगा यदि इनलाइन का उपयोग करने का एक साइड-इफ़ेक्ट होगा - हमेशा फ़ंक्शन के एक गैर-इनलाइन संस्करण को उत्सर्जित करने के लिए - जो कि इसके नाम से पता चलता है, उसके विपरीत है।
इनलाइन फ़ंक्शंस के लिए पूर्णतया एक बाहरी रूप से दृश्यमान फ़ंक्शन उदाहरण प्रदान करने की आवश्यकता के बारे में और पहुंच योग्य कोड के साथ परिणामी समस्या के बारे में सी99 की टिप्पणियाँ यथोचित परिवर्तनों के साथ जीएनयू89 पर भी लागू होती हैं।
संस्करण 4.2 तक और इसमें सम्मलित जीसीसी ने जीएनयू89 इनलाइन शब्दार्थ का उपयोग किया, तब भी जब -एसटीडी =सी99 स्पष्ट रूप से निर्दिष्ट किया गया था।[6] संस्करण 5 के साथ,[5] जीसीसी ने जीएनयू89 से जीएनयू11 बोली में स्विच किया, जिससे डिफ़ॉल्ट रूप से सी99 इनलाइन शब्दार्थ को प्रभावी ढंग से सक्षम किया गया। इसके अतिरिक्त जीएनयू89 शब्दार्थ का उपयोग करने के लिए, उन्हें स्पष्ट रूप से सक्षम करना होगा, या तो -एसटीडी =जीएनयू89 के साथ या, मात्र इनलाइनिंग को प्रभावित करने के लिए, -एफजीएनयू89-इनलाइन, या सभी इनलाइन घोषणाओं में जीएनयू_इनलाइन विशेषता जोड़कर। सी99 शब्दार्थ सुनिश्चित करने के लिए, या तो -एसटीडी =सी99, -एसटीडी =सी11, -एसटीडी =जीएनयू99 या -एसटीडी =जीएनयू11 (-एफजीएनयू89-इनलाइन के बिना) का उपयोग किया जा सकता है।[3]
सी ++
सी ++ में, इनलाइन परिभाषित एक फ़ंक्शन, यदि आवश्यक हो, अनुवाद इकाइयों के बीच साझा किए गए फ़ंक्शन को उत्सर्जित करेगा, सामान्यतः इसे ऑब्जेक्ट फ़ाइल के सामान्य अनुभाग में डालकर जिसके लिए इसकी आवश्यकता होती है। फ़ंक्शन की परिभाषा हर जगह समान होनी चाहिए, निरंतर इनलाइन क्वालिफायर के साथ। सी ++ में, एक्सटर्नल इनलाइन इनलाइन के समान है। सी ++ दृष्टिकोण के लिए तर्क यह है कि यह प्रोग्रामर के लिए सबसे सुविधाजनक विधि है, क्योंकि पहुंच योग्य कोड को हटाने के लिए कोई विशेष सावधानी नहीं बरतनी चाहिए और, सामान्य कार्यों की तरह, इससे कोई फर्क नहीं पड़ता कि बाहरी निर्दिष्ट है या नहीं। इनलाइन क्वालिफायर स्वचालित रूप से क्लास परिभाषा के भाग के रूप में परिभाषित फ़ंक्शन में जोड़ा जाता है।
आर्मसीसी
सी90 मोड में आर्मसीसी बाहरी इनलाइन और इनलाइन शब्दार्थ प्रदान करता है जो सी ++ के समान हैं: ऐसी परिभाषाएँ यदि आवश्यक हो तो अनुवाद इकाइयों के बीच साझा किए गए फ़ंक्शन का उत्सर्जन करेंगी। सी99 मोड में, एक्सटर्नल इनलाइन निरंतर एक फ़ंक्शन उत्सर्जित करता है, लेकिन सी ++ की तरह, इसे अनुवाद इकाइयों के बीच साझा किया जाएगा। इस प्रकार, एक ही फ़ंक्शन को विभिन्न अनुवाद इकाइयों में एक्सटर्नल इनलाइन परिभाषित किया जा सकता है।[7] यह अप्रारंभीकृत वैश्विक चर की कई गैर-बाहरी परिभाषाओं के लिए यूनिक्स सी कंपाइलर्स[8] के पारंपरिक व्यवहार से मेल खाता है।
प्रतिबंध
किसी इनलाइन फ़ंक्शन का पता लेने के लिए किसी भी स्थिति में उस फ़ंक्शन की गैर-इनलाइन प्रतिलिपि के लिए कोड की आवश्यकता होती है।
सी99 में, एक इनलाइन या बाहरी इनलाइन फ़ंक्शन को स्थिर वैश्विक चर तक नहीं पहुंचना चाहिए या गैर-कॉन्स्ट स्थिर स्थानीय चर को परिभाषित नहीं करना चाहिए। स्थिर स्थिर स्थानीय चर भिन्न-भिन्न अनुवाद इकाइयों में भिन्न-भिन्न ऑब्जेक्ट हो भी सकते हैं और नहीं भी, यह इस बात पर निर्भर करता है कि फ़ंक्शन इनलाइन किया गया था या कॉल किया गया था। मात्र स्थिर इनलाइन परिभाषाएँ बिना किसी प्रतिबंध के आंतरिक लिंकेज वाले पहचानकर्ताओं को संदर्भित कर सकती हैं; वे प्रत्येक अनुवाद इकाई में भिन्न-भिन्न वस्तुएँ होंगी। सी++ में, कॉन्स्ट और नॉन-कॉन्स्ट दोनों स्थिर स्थानीय की अनुमति है और वे सभी अनुवाद इकाइयों में एक ही ऑब्जेक्ट को संदर्भित करते हैं।
जीसीसी इनलाइन फ़ंक्शंस नहीं कर सकता है यदि[3]
- वे विविध हैं,
- कंप्यूटेड गोटो का उपयोग करें
- गैर-स्थानीय गोटो का उपयोग करें
- नेस्टेड फंक्शन का उपयोग करें
- सेटजेएमपी का उपयोग करें
- __बिल्टिन_लॉन्गजम्प का उपयोग करें
- __बिल्टिन_रिटर्न का उपयोग करें, या
- __बिल्टिन_अप्लाई_आर्ग्स का उपयोग करें
एमएसडीएन पर माइक्रोसॉफ्ट विनिर्देशों के आधार पर, एमएस विज़ुअल सी ++ इनलाइन नहीं कर सकता (__फ़ोर्सइनलाइन के साथ भी नहीं), यदि
- फ़ंक्शन या उसके कॉलर को /Ob0 (डीबग बिल्ड के लिए डिफ़ॉल्ट विकल्प) के साथ संकलित किया गया है।
- फ़ंक्शन और कॉलर विभिन्न प्रकार के अपवाद हैंडलिंग (एक में सी ++ अपवाद हैंडलिंग, दूसरे में संरचित अपवाद हैंडलिंग) का उपयोग करते हैं।
- फ़ंक्शन में एक परिवर्तनीय तर्क सूची है।
- फ़ंक्शन इनलाइन असेंबली का उपयोग करता है, जब तक कि इसे /Og, /Ox, /O1, या /O2 के साथ संकलित नहीं किया जाता है।
- फ़ंक्शन रिकर्सन (कंप्यूटर विज्ञान) है और
#pragma inline_recursion(on)
के साथ नहीं है। प्राग्मा के साथ, पुनरावर्ती फ़ंक्शन 16 कॉल की डिफ़ॉल्ट गहराई पर इनलाइन होते हैं। इनलाइनिंग गहराई को कम करने के लिए, इनलाइन_डेप्थ प्राग्मा का उपयोग किया जाता है। - यह फ़ंक्शन आभासी फंक्शन है और इसे वर्चुअली कहा जाता है। वर्चुअल फ़ंक्शंस पर सीधी कॉल को इनलाइन किया जा सकता है।
- प्रोग्राम फ़ंक्शन का पता लेता है और पॉइंटर के माध्यम से फ़ंक्शन पर कॉल किया जाता है। जिन कार्यों का पता लिया गया है, उनके लिए सीधी कॉल को इनलाइन किया जा सकता है।
- फ़ंक्शन को नेक्ड __देकलस्पेस संशोधक के साथ भी चिह्नित किया गया है।
समस्याएं
यह भी देखें: इनलाइन विस्तार § प्रदर्शन पर प्रभाव
सामान्यतः इनलाइन विस्तार की समस्याओं के अतिरिक्त (देखें इनलाइन विस्तार § प्रदर्शन पर प्रभाव), भाषा सुविधा के रूप में इनलाइन फ़ंक्शन कई कारणों से उतने मूल्यवान नहीं हो सकते जितने वे दिखाई देते हैं:
- अधिकांशतः, एक कंपाइलर यह तय करने के लिए मानव से उत्तम स्थिति में होता है कि किसी विशेष फ़ंक्शन को इनलाइन किया जाना चाहिए या नहीं। कभी-कभी कंपाइलर उतने फ़ंक्शन इनलाइन करने में सक्षम नहीं हो सकता जितना प्रोग्रामर इंगित करता है।
- ध्यान देने योग्य एक महत्वपूर्ण बात यह है कि कोड (इनलाइन फ़ंक्शन का) उसके क्लाइंट (कॉलिंग फ़ंक्शन) के सामने आ जाता है।
- जैसे-जैसे फ़ंक्शंस विकसित होते हैं, वे इनलाइनिंग के लिए उपयुक्त हो सकते हैं जहाँ वे पहले नहीं थे, या अब इनलाइनिंग के लिए उपयुक्त नहीं रह जाते जहाँ वे पहले थे। चूंकि किसी फ़ंक्शन को इनलाइन करना या अन-इनलाइन करना मैक्रोज़ में कनवर्ट करने से आसान है, फिर भी इसके लिए अतिरिक्त रखरखाव की आवश्यकता होती है जो सामान्यतः अपेक्षाकृत कम लाभ देता है।
- देशी सी-आधारित संकलन प्रणालियों में प्रसार में उपयोग किए जाने वाले इनलाइन फ़ंक्शन संकलन समय को बढ़ा सकते हैं, क्योंकि उनके बॉडी के मध्यवर्ती प्रतिनिधित्व को प्रत्येक कॉल साइट में कॉपी किया जाता है।
- सी99 में इनलाइन के विनिर्देशन के लिए फ़ंक्शन की पूर्णतया एक बाहरी परिभाषा की आवश्यकता होती है, यदि इसका उपयोग कहीं किया जाता है। यदि ऐसी कोई परिभाषा प्रोग्रामर द्वारा प्रदान नहीं की गई थी, तो इससे आसानी से लिंकर त्रुटियां हो सकती हैं। ऑप्टिमाइज़ेशन बंद होने पर ऐसा हो सकता है, जो सामान्यतः इनलाइनिंग को रोकता है। दूसरी ओर, परिभाषाएँ जोड़ने से कोड अगम्य हो सकता है यदि प्रोग्रामर उन्हें लिंक करने के लिए लाइब्रेरी में डालकर, लिंक टाइम ऑप्टिमाइज़ेशन या स्टैटिक इनलाइन का उपयोग करके सावधानी से नहीं बचता है।
- सी ++ में, इसका उपयोग करने वाले प्रत्येक मॉड्यूल (अनुवाद इकाई) में एक इनलाइन फ़ंक्शन को परिभाषित करना आवश्यक है, जबकि एक सामान्य फ़ंक्शन को मात्र एक मॉड्यूल में परिभाषित किया जाना चाहिए। अन्यथा किसी एक मॉड्यूल को अन्य सभी मॉड्यूल से स्वतंत्र रूप से संकलित करना संभव नहीं होगा। कंपाइलर के आधार पर, इसके कारण प्रत्येक संबंधित ऑब्जेक्ट फ़ाइल में फ़ंक्शन के कोड की एक प्रति सम्मलित हो सकती है, प्रत्येक मॉड्यूल के लिए कुछ उपयोग के साथ जिसे इनलाइन नहीं किया जा सकता है।
- एम्बेडेड सॉफ़्टवेयर में, अधिकांशतः कुछ कार्यों को में,"प्रागमा" स्टेटमेंट जैसे विशेष कंपाइलर निर्देशों के उपयोग द्वारा कुछ कोड अनुभागों में रखने की आवश्यकता होती है। कभी-कभी, एक मेमोरी सेगमेंट में एक फ़ंक्शन को दूसरे मेमोरी सेगमेंट में एक फ़ंक्शन को कॉल करने की आवश्यकता हो सकती है, और यदि कॉल किए गए फ़ंक्शन की इनलाइनिंग होती है, तो कॉल किए गए फ़ंक्शन का कोड उस सेगमेंट में समाप्त हो सकता है जहां यह नहीं होना चाहिए। उदाहरण के लिए, उच्च-प्रदर्शन मेमोरी सेगमेंट कोड स्पेस में बहुत सीमित हो सकते हैं, और यदि ऐसे स्पेस में उपलब्ध एक फ़ंक्शन किसी अन्य बड़े फ़ंक्शन को कॉल करता है जो उच्च-प्रदर्शन अनुभाग में नहीं होता है और कॉल किया गया फ़ंक्शन अनुचित रूप से इनलाइन हो जाता है, तो इससे उच्च-प्रदर्शन मेमोरी सेगमेंट में कोड स्थान समाप्त हो सकता है। फ़ंक्शन इनलाइन न हो जाएं इस कारण से, कभी-कभी यह सुनिश्चित करना आवश्यक होता है।
उद्धरण
- "एक फ़ंक्शन घोषणा [...] एक इनलाइन विनिर्देशक के साथ एक इनलाइन फ़ंक्शन घोषित करता है। इनलाइन विनिर्देशक कार्यान्वयन को इंगित करता है कि कॉल के बिंदु पर फ़ंक्शन बॉडी के इनलाइन प्रतिस्थापन को सामान्य फ़ंक्शन कॉल तंत्र के लिए प्राथमिकता दी जानी है। एक कार्यान्वयन कॉल के बिंदु पर इस इनलाइन प्रतिस्थापन को निष्पादित करने की आवश्यकता नहीं है; चूंकि, यदि इस इनलाइन प्रतिस्थापन को छोड़ दिया गया हो, 7.1.2 द्वारा परिभाषित इनलाइन फ़ंक्शन के अन्य नियमों का अभी भी सम्मान किया जा सकता है।
- — आईएसओ/आईईसी 14882:2011, वर्तमान सी++ मानक, खंड 7.1.2
- "इनलाइन फ़ंक्शन विनिर्देशक के साथ घोषित एक फ़ंक्शन एक इनलाइन फ़ंक्शन है। [...] एक फ़ंक्शन को इनलाइन फ़ंक्शन बनाने से पता चलता है कि फ़ंक्शन पर कॉल जितनी तेज़ हो सके। ऐसे सुझाव किस हद तक प्रभावी हैं यह कार्यान्वयन-परिभाषित है ( फ़ुटनोट: उदाहरण के लिए, एक कार्यान्वयन कभी भी इनलाइन प्रतिस्थापन नहीं कर सकता है, या मात्र इनलाइन घोषणा के दायरे में कॉल के लिए इनलाइन प्रतिस्थापन कर सकता है।)
- "[...] एक इनलाइन परिभाषा फ़ंक्शन के लिए बाहरी परिभाषा प्रदान नहीं करती है, और किसी अन्य अनुवाद इकाई में बाहरी परिभाषा को प्रतिबंधित नहीं करती है। एक इनलाइन परिभाषा बाहरी परिभाषा का एक विकल्प प्रदान करती है, जिसका उपयोग एक अनुवादक किसी भी कार्य को लागू करने के लिए कर सकता है। उसी अनुवाद इकाई में फ़ंक्शन को कॉल करें। यह निर्दिष्ट नहीं है कि फ़ंक्शन पर कॉल इनलाइन परिभाषा या बाहरी परिभाषा का उपयोग करती है या नहीं," — आईएसओ 9899:1999(ई), सी99 मानक, खंड 6.7.4
यह भी देखें
संदर्भ
- ↑ 1.0 1.1 Meyers, Randy (July 1, 2002). "The New C: Inline Functions".
{{cite journal}}
: Cite journal requires|journal=
(help) - ↑ 2.0 2.1 "Inline Functions in C".
- ↑ 3.0 3.1 3.2 3.3 "Using the GNU Compiler Collection (GCC): Inline".
- ↑ "Josef "Jeff" Sipek » GNU inline vs. C99 inline".
- ↑ 5.0 5.1 "Porting to GCC 5 - GNU Project".
- ↑ "Ian Lance Taylor - Clean up extern inline".
- ↑ "Documentation – Arm Developer".
- ↑ gcc manual page, description of
-fno-common
- JANA, DEBASISH (1 January 2005). C++ AND OBJECT-ORIENTED PROGRAMMING PARADIGM. PHI Learning Pvt. Ltd. ISBN 978-81-203-2871-6.
- Sengupta, Probal (1 August 2004). Object-Oriented Programming: Fundamentals And Applications. PHI Learning Pvt. Ltd. ISBN 978-81-203-1258-6.
- Svenk, Goran (2003). Object-oriented Programming: Using C++ for Engineering and Technology. Cengage Learning. ISBN 0-7668-3894-3.
- Balagurusamy (2013). Object Oriented Programming with C++. Tata McGraw-Hill Education. ISBN 978-1-259-02993-6.
- Kirch-Prinz, Ulla; Prinz, Peter (2002). A Complete Guide to Programming in C++. Jones & Bartlett Learning. ISBN 978-0-7637-1817-6.
- Conger, David (2006). Creating Games in C++: A Step-by-step Guide. New Riders. ISBN 978-0-7357-1434-2.
- Skinner, M. T. (1992). The Advanced C++ Book. Silicon Press. ISBN 978-0-929306-10-0.
- Love (1 September 2005). Linux Kernel Development. Pearson Education. ISBN 978-81-7758-910-8.
- DEHURI, SATCHIDANANDA; JAGADEV, ALOK KUMAR; RATH, AMIYA KUMAR (8 May 2007). OBJECT-ORIENTED PROGRAMMING USING C++. PHI Learning Pvt. Ltd. ISBN 978-81-203-3085-6.
बाहरी संबंध
- Inline functions with the जीएनयू Compiler Collection (GCC)
- Summary of "inline" semantics in C and C++, by LLVM contributor David Chisnall