इनलाइन फ़ंक्शन: Difference between revisions

From Vigyanwiki
No edit summary
No edit summary
Line 30: Line 30:


== मानक समर्थन ==
== मानक समर्थन ==
C++ और [[C99]], लेकिन इसके पूर्ववर्ती K&R C और C89 (C संस्करण) के लिए समर्थन नहीं है <code>inline</code> कार्य, चूंकि विभिन्न शब्दार्थों के साथ। दोनों ही स्थितियों में, <code>inline</code> इनलाइनिंग को मजबूर नहीं करता है; संकलक फ़ंक्शन को इनलाइन नहीं करने का चयन करने के लिए स्वतंत्र है, या मात्र कुछ स्थितियों में। भिन्न-भिन्न कंपाइलर इस बात में भिन्न होते हैं कि इनलाइन में वे कितने जटिल कार्य कर सकते हैं। [[विजुअल सी प्लस प्लस]] | माइक्रोसॉफ्ट विज़ुअल सी++ और [[जीएनयू संकलक संग्रह]] जैसे मेनस्ट्रीम सी++ कंपाइलर्स एक ऐसे विकल्प का समर्थन करते हैं जो कंपाइलर्स को स्वचालित रूप से किसी भी उपयुक्त फ़ंक्शन को इनलाइन करने देता है, यहां तक ​​​​कि उन लोगों के रूप में चिह्नित नहीं किया गया है। <code>inline</code> कार्य करता है। चूंकि, मात्र छोड़ना <code>inline</code> कीवर्ड को संकलक को सभी इनलाइनिंग निर्णय लेने देना संभव नहीं है, क्योंकि लिंकर तब विभिन्न अनुवाद इकाइयों में डुप्लिकेट परिभाषाओं के बारे में शिकायत करेगा। यह है क्योंकि <code>inline</code> न मात्र संकलक को संकेत देता है कि फ़ंक्शन को रेखांकित किया जाना चाहिए, इसका प्रभाव यह भी है कि संकलक फ़ंक्शन की कॉल करने योग्य आउट-ऑफ-लाइन प्रति उत्पन्न करेगा (इनलाइन फ़ंक्शंस के #Storage वर्ग देखें)।
C++ और [[C99]], लेकिन इसके पूर्ववर्ती K&R C और C89 के पास इनलाइन फ़ंक्शंस के लिए समर्थन नहीं है, हालांकि अलग-अलग शब्दार्थ के साथ। दोनों ही मामलों में, इनलाइन इनलाइनिंग को बाध्य नहीं करता है; संकलक यह चुनने के लिए स्वतंत्र है कि वह फ़ंक्शन को बिल्कुल भी इनलाइन न करे, या केवल कुछ मामलों में। भिन्न-भिन्न संकलक इस बात में भिन्न होते हैं कि वे कितने जटिल फ़ंक्शन को इनलाइन में प्रबंधित कर सकते हैं।  [[विजुअल सी प्लस प्लस]] | माइक्रोसॉफ्ट विज़ुअल सी++ और जीसीसी जैसे मुख्यधारा सी++ संकलक एक विकल्प का समर्थन करते हैं जो कंपाइलरों को किसी भी उपयुक्त फ़ंक्शन को स्वचालित रूप से इनलाइन करने देता है, यहां तक ​​कि उन लोगों को भी इनलाइन फ़ंक्शन के रूप में चिह्नित नहीं किया जाता है। हालाँकि, कंपाइलर को सभी इनलाइनिंग निर्णय लेने देने के लिए इनलाइन कीवर्ड को छोड़ना संभव नहीं है, क्योंकि लिंकर तब विभिन्न अनुवाद इकाइयों में डुप्लिकेट परिभाषाओं के बारे में शिकायत करेगा। ऐसा इसलिए है क्योंकि इनलाइन न केवल कंपाइलर को संकेत देता है कि फ़ंक्शन को इनलाइन किया जाना चाहिए, बल्कि इसका इस पर भी प्रभाव पड़ता है कि कंपाइलर फ़ंक्शन की कॉल करने योग्य आउट-ऑफ़-लाइन प्रतिलिपि उत्पन्न करेगा या नहीं (इनलाइन फ़ंक्शंस की स्टोरेज क्लास देखें)।
C++ और [[C99]], लेकिन इसके पूर्ववर्ती K&R C और C89 के पास इनलाइन फ़ंक्शंस के लिए समर्थन नहीं है, हालांकि अलग-अलग शब्दार्थ के साथ। दोनों ही मामलों में, इनलाइन इनलाइनिंग को बाध्य नहीं करता है; संकलक यह चुनने के लिए स्वतंत्र है कि वह फ़ंक्शन को बिल्कुल भी इनलाइन न करे, या केवल कुछ मामलों में। भिन्न-भिन्न संकलक इस बात में भिन्न होते हैं कि वे कितने जटिल फ़ंक्शन को इनलाइन में प्रबंधित कर सकते हैं।  [[विजुअल सी प्लस प्लस]] | माइक्रोसॉफ्ट विज़ुअल सी++ और जीसीसी जैसे मुख्यधारा सी++ संकलक एक विकल्प का समर्थन करते हैं जो कंपाइलरों को किसी भी उपयुक्त फ़ंक्शन को स्वचालित रूप से इनलाइन करने देता है, यहां तक ​​कि उन लोगों को भी इनलाइन फ़ंक्शन के रूप में चिह्नित नहीं किया जाता है। हालाँकि, कंपाइलर को सभी इनलाइनिंग निर्णय लेने देने के लिए इनलाइन कीवर्ड को छोड़ना संभव नहीं है, क्योंकि लिंकर तब विभिन्न अनुवाद इकाइयों में डुप्लिकेट परिभाषाओं के बारे में शिकायत करेगा। ऐसा इसलिए है क्योंकि इनलाइन न केवल कंपाइलर को संकेत देता है कि फ़ंक्शन को इनलाइन किया जाना चाहिए, बल्कि इसका इस पर भी प्रभाव पड़ता है कि कंपाइलर फ़ंक्शन की कॉल करने योग्य आउट-ऑफ़-लाइन प्रतिलिपि उत्पन्न करेगा या नहीं (इनलाइन फ़ंक्शंस की स्टोरेज क्लास देखें)।


== अमानक एक्सटेंशन ==
== अमानक एक्सटेंशन ==
[[GNU C]], बोली gnu89 के हिस्से के रूप में जो इसे प्रदान करता है, के लिए समर्थन है <code>inline</code> C89 के विस्तार के रूप में। चूंकि, शब्दार्थ C++ और C99 दोनों से भिन्न है। C90 मोड में armcc भी प्रदान करता है <code>inline</code> एक गैर-मानक विस्तार के रूप में, शब्दार्थ के साथ gnu89 और C99 से भिन्न।
[[GNU C,]] बोली gnu89 के भाग के रूप में, जो यह प्रदान करता है, C89 के विस्तार के रूप में इनलाइन के लिए समर्थन है। हालाँकि, शब्दार्थ C++ और C99 दोनों से भिन्न है। C90 मोड में Armcc एक गैर-मानक एक्सटेंशन के रूप में इनलाइन भी प्रदान करता है, जिसका शब्दार्थ gnu89 और C99 से भिन्न है।


कुछ कार्यान्वयन एक साधन प्रदान करते हैं जिसके द्वारा संकलक को एक फ़ंक्शन को इनलाइन करने के लिए मजबूर किया जाता है, सामान्यतः कार्यान्वयन-विशिष्ट घोषणा विनिर्देशकों के माध्यम से:
कुछ कार्यान्वयन एक साधन प्रदान करते हैं जिसके द्वारा संकलक को किसी फ़ंक्शन को इनलाइन करने के लिए मजबूर किया जाता है, सामान्यतः पर कार्यान्वयन-विशिष्ट घोषणा विनिर्देशकों के माध्यम से:
* माइक्रोसॉफ्ट विज़ुअल सी ++: <code>__forceinline</code>
* माइक्रोसॉफ्ट विज़ुअल सी ++: <code>__forceinline</code>
* जीसीसी या क्लैंग: <code>__attribute__((always_inline))</code> या <code>__attribute__((__always_inline__))</code>, जिसका पश्चात वाला उपयोगकर्ता-परिभाषित मैक्रो नाम के साथ विरोध से बचने के लिए उपयोगी है <code>always_inline</code>.
* जीसीसी या क्लैंग: __attribute__((always_inline)) या __attribute__((__always_inline__)), जिनमें से बाद वाला हमेशा_इनलाइन नामक उपयोगकर्ता-परिभाषित मैक्रो के साथ टकराव से बचने के लिए उपयोगी है।
इसके अंधाधुंध उपयोग के परिणामस्वरूप बड़ा कोड (फूला हुआ निष्पादन योग्य फ़ाइल), न्यूनतम या कोई प्रदर्शन लाभ नहीं हो सकता है, और कुछ स्थितियों में प्रदर्शन में कमी भी हो सकती है। इसके अतिरिक्त, कंपाइलर सभी परिस्थितियों में फ़ंक्शन को इनलाइन नहीं कर सकता है, यदि इनलाइनिंग मजबूर हो; इस स्थितियाँ में जीसीसी और विजुअल सी ++ दोनों चेतावनियां उत्पन्न करते हैं।
इसके अंधाधुंध उपयोग के परिणामस्वरूप बड़ा कोड (फूली हुई निष्पादन योग्य फ़ाइल), न्यूनतम या कोई प्रदर्शन लाभ नहीं हो सकता है, और कुछ मामलों में प्रदर्शन में हानि भी हो सकती है। इसके अलावा, कंपाइलर सभी परिस्थितियों में फ़ंक्शन को इनलाइन नहीं कर सकता, भले ही इनलाइनिंग को मजबूर किया गया हो; इस मामले में जीसीसी और विजुअल सी ++ दोनों चेतावनियाँ उत्पन्न करते हैं।


इनलाइनिंग को मजबूर करना उपयोगी है यदि
इनलाइनिंग को मजबूर करना उपयोगी है  
* <code>inline</code> संकलक द्वारा सम्मानित नहीं किया जाता है (संकलक लागत/लाभ विश्लेषक द्वारा अनदेखा किया जाता है), और
* कंपाइलर द्वारा इनलाइन का सम्मान नहीं किया जाता है (कंपाइलर लागत/लाभ विश्लेषक द्वारा अनदेखा किया जाता है), और
* इनलाइनिंग से आवश्यक प्रदर्शन में वृद्धि होती है
* इनलाइनिंग के परिणामस्वरूप आवश्यक प्रदर्शन में वृद्धि होती है


कोड पोर्टेबिलिटी के लिए, निम्नलिखित प्रीप्रोसेसर निर्देशों का उपयोग किया जा सकता है:
कोड पोर्टेबिलिटी के लिए, निम्नलिखित प्रीप्रोसेसर निर्देशों का उपयोग किया जा सकता है:
Line 65: Line 63:


== इनलाइन फ़ंक्शंस का संग्रहण वर्ग ==
== इनलाइन फ़ंक्शंस का संग्रहण वर्ग ==
<code>static inline</code> सभी C बोलियों और C++ में समान प्रभाव है। यदि आवश्यक हो तो यह स्थानीय रूप से दृश्यमान (आउट-ऑफ-लाइन प्रति) फ़ंक्शन का उत्सर्जन करेगा।
स्टैटिक इनलाइन का सभी C बोलियों और C++ में समान प्रभाव होता है। यदि आवश्यक हो तो यह स्थानीय रूप से दृश्यमान (आउट-ऑफ़-लाइन कॉपी) फ़ंक्शन का उत्सर्जन करेगा।
 
स्टोरेज क्लास के बावजूद, कंपाइलर इनलाइन क्वालीफायर को अनदेखा कर सकता है और सभी सी बोलीभाषाओं और सी++ में फ़ंक्शन कॉल उत्पन्न कर सकता है।


स्टोरेज क्लास के अतिरिक्त, कंपाइलर अनदेखा कर सकता है <code>inline</code> क्वालीफायर और सभी सी बोलियों और सी ++ में फ़ंक्शन कॉल उत्पन्न करें।
इनलाइन फ़ंक्शंस पर लागू या लागू नहीं होने पर स्टोरेज क्लास एक्सटर्न का प्रभाव C बोलियों<ref name="inline-c99-vs-gnu">{{Cite web|url=http://www.greenend.org.uk/rjk/tech/inline.html|title = Inline Functions in C}}</ref> और C++ के बीच भिन्न होता है।<ref name="gcc-inline">{{Cite web|url=https://gcc.gnu.org/onlinedocs/gcc-7.1.0/gcc/Inline.html|title = Using the GNU Compiler Collection (GCC): Inline}}</ref>


भंडारण वर्ग का प्रभाव <code>extern</code> जब लागू किया जाता है या लागू नहीं किया जाता है <code>inline</code> कार्य सी बोलियों के बीच भिन्न होते हैं<ref name="inline-c99-vs-gnu">{{Cite web|url=http://www.greenend.org.uk/rjk/tech/inline.html|title = Inline Functions in C}}</ref> और सी ++।<ref name="gcc-inline">{{Cite web|url=https://gcc.gnu.org/onlinedocs/gcc-7.1.0/gcc/Inline.html|title = Using the GNU Compiler Collection (GCC): Inline}}</ref>





Revision as of 16:11, 8 July 2023

सी (प्रोग्रामिंग भाषा ) और सी ++ प्रोग्रामिंग भाषाओं में, एक इनलाइन फ़ंक्शन कीवर्ड (कंप्यूटर प्रोग्रामिंग) inline के साथ योग्य है; यह दो उद्देश्यों को पूरा करता है:

  1. यह एक कंपाइलर निर्देश के रूप में कार्य करता है जो सुझाव देता है (लेकिन इसकी आवश्यकता नहीं है) कि कंपाइलर इनलाइन विस्तार करके फ़ंक्शन के बॉडी को इनलाइन प्रतिस्थापित करता है, अर्थात प्रत्येक फ़ंक्शन कॉल के पते पर फ़ंक्शन कोड डालकर, जिससे फ़ंक्शन कॉल के ओवरहेड को बचाया जा सकता है। इस संबंध में यह रजिस्टर registerस्टोरेज क्लास निर्दिष्टकर्ता के अनुरूप है, जो इसी प्रकार एक अनुकूलन संकेत प्रदान करता है।[1]
  2. इनलाइन का दूसरा उद्देश्य लिंकेज व्यवहार को बदलना है; इसका विवरण जटिल है। यह सी/सी++ भिन्न संकलन + लिंकेज मॉडल के कारण आवश्यक है, विशेष रूप से क्योंकि फ़ंक्शन की परिभाषा (बॉडी) को उन सभी अनुवाद इकाई (प्रोग्रामिंग) में डुप्लिकेट किया जाना चाहिए जहां इसका उपयोग किया जाता है, ताकि संकलन के दौरान इनलाइनिंग की अनुमति मिल सके, यदि फ़ंक्शन में बाहरी लिंकेज (सॉफ़्टवेयर) है, लिंकिंग के दौरान टकराव का कारण बनता है (यह बाहरी प्रतीकों की विशिष्टता का उल्लंघन करता है)। सी और सी ++ (और जीएनयू सी और विजुअल सी ++ जैसी बोलियां) इसे भिन्न-भिन्न विधियों से हल करती हैं।[1]


उदाहरण

एक inline function को C या C++ में इस प्रकार लिखा जा सकता है:

inline void swap(int *m, int *n)
{
    int tmp = *m;
    *m = *n;
    *n = tmp;
}

फिर, निम्नलिखित जैसा एक कथन:

swap(&x, &y);

इसका अनुवाद किया जा सकता है (यदि कंपाइलर इनलाइनिंग करने का निर्णय लेता है, जिसके लिए आमतौर पर अनुकूलन को सक्षम करने की आवश्यकता होती है):

int tmp = x;
x = y;
y = tmp;

बहुत सारे स्वैप करते हुए सॉर्टिंग एल्गोरिदम लागू करते समय, यह निष्पादन गति को बढ़ा सकता है।

मानक समर्थन

C++ और C99, लेकिन इसके पूर्ववर्ती K&R C और C89 के पास इनलाइन फ़ंक्शंस के लिए समर्थन नहीं है, हालांकि अलग-अलग शब्दार्थ के साथ। दोनों ही मामलों में, इनलाइन इनलाइनिंग को बाध्य नहीं करता है; संकलक यह चुनने के लिए स्वतंत्र है कि वह फ़ंक्शन को बिल्कुल भी इनलाइन न करे, या केवल कुछ मामलों में। भिन्न-भिन्न संकलक इस बात में भिन्न होते हैं कि वे कितने जटिल फ़ंक्शन को इनलाइन में प्रबंधित कर सकते हैं। विजुअल सी प्लस प्लस | माइक्रोसॉफ्ट विज़ुअल सी++ और जीसीसी जैसे मुख्यधारा सी++ संकलक एक विकल्प का समर्थन करते हैं जो कंपाइलरों को किसी भी उपयुक्त फ़ंक्शन को स्वचालित रूप से इनलाइन करने देता है, यहां तक ​​कि उन लोगों को भी इनलाइन फ़ंक्शन के रूप में चिह्नित नहीं किया जाता है। हालाँकि, कंपाइलर को सभी इनलाइनिंग निर्णय लेने देने के लिए इनलाइन कीवर्ड को छोड़ना संभव नहीं है, क्योंकि लिंकर तब विभिन्न अनुवाद इकाइयों में डुप्लिकेट परिभाषाओं के बारे में शिकायत करेगा। ऐसा इसलिए है क्योंकि इनलाइन न केवल कंपाइलर को संकेत देता है कि फ़ंक्शन को इनलाइन किया जाना चाहिए, बल्कि इसका इस पर भी प्रभाव पड़ता है कि कंपाइलर फ़ंक्शन की कॉल करने योग्य आउट-ऑफ़-लाइन प्रतिलिपि उत्पन्न करेगा या नहीं (इनलाइन फ़ंक्शंस की स्टोरेज क्लास देखें)।

अमानक एक्सटेंशन

GNU C, बोली gnu89 के भाग के रूप में, जो यह प्रदान करता है, C89 के विस्तार के रूप में इनलाइन के लिए समर्थन है। हालाँकि, शब्दार्थ C++ और C99 दोनों से भिन्न है। C90 मोड में Armcc एक गैर-मानक एक्सटेंशन के रूप में इनलाइन भी प्रदान करता है, जिसका शब्दार्थ gnu89 और C99 से भिन्न है।

कुछ कार्यान्वयन एक साधन प्रदान करते हैं जिसके द्वारा संकलक को किसी फ़ंक्शन को इनलाइन करने के लिए मजबूर किया जाता है, सामान्यतः पर कार्यान्वयन-विशिष्ट घोषणा विनिर्देशकों के माध्यम से:

  • माइक्रोसॉफ्ट विज़ुअल सी ++: __forceinline
  • जीसीसी या क्लैंग: __attribute__((always_inline)) या __attribute__((__always_inline__)), जिनमें से बाद वाला हमेशा_इनलाइन नामक उपयोगकर्ता-परिभाषित मैक्रो के साथ टकराव से बचने के लिए उपयोगी है।

इसके अंधाधुंध उपयोग के परिणामस्वरूप बड़ा कोड (फूली हुई निष्पादन योग्य फ़ाइल), न्यूनतम या कोई प्रदर्शन लाभ नहीं हो सकता है, और कुछ मामलों में प्रदर्शन में हानि भी हो सकती है। इसके अलावा, कंपाइलर सभी परिस्थितियों में फ़ंक्शन को इनलाइन नहीं कर सकता, भले ही इनलाइनिंग को मजबूर किया गया हो; इस मामले में जीसीसी और विजुअल सी ++ दोनों चेतावनियाँ उत्पन्न करते हैं।

इनलाइनिंग को मजबूर करना उपयोगी है

  • कंपाइलर द्वारा इनलाइन का सम्मान नहीं किया जाता है (कंपाइलर लागत/लाभ विश्लेषक द्वारा अनदेखा किया जाता है), और
  • इनलाइनिंग के परिणामस्वरूप आवश्यक प्रदर्शन में वृद्धि होती है

कोड पोर्टेबिलिटी के लिए, निम्नलिखित प्रीप्रोसेसर निर्देशों का उपयोग किया जा सकता है:

#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


इनलाइन फ़ंक्शंस का संग्रहण वर्ग

स्टैटिक इनलाइन का सभी C बोलियों और C++ में समान प्रभाव होता है। यदि आवश्यक हो तो यह स्थानीय रूप से दृश्यमान (आउट-ऑफ़-लाइन कॉपी) फ़ंक्शन का उत्सर्जन करेगा।

स्टोरेज क्लास के बावजूद, कंपाइलर इनलाइन क्वालीफायर को अनदेखा कर सकता है और सभी सी बोलीभाषाओं और सी++ में फ़ंक्शन कॉल उत्पन्न कर सकता है।

इनलाइन फ़ंक्शंस पर लागू या लागू नहीं होने पर स्टोरेज क्लास एक्सटर्न का प्रभाव C बोलियों[2] और C++ के बीच भिन्न होता है।[3]


सी 99

C99 में, एक फ़ंक्शन परिभाषित किया गया inline कभी नहीं होगा, और एक फ़ंक्शन परिभाषित किया गया है extern inline निरंतर बाहरी रूप से दिखाई देने वाले फ़ंक्शन का उत्सर्जन करेगा। सी ++ के विपरीत, अनुवाद इकाइयों के बीच साझा किए गए बाहरी रूप से दृश्यमान फ़ंक्शन को मात्र आवश्यक होने पर उत्सर्जित करने का कोई विधि नहीं है।

यदि inline घोषणाओं को मिलाया गया है extern inline घोषणाएं या अयोग्य घोषणाओं के साथ (अर्थात।, बिना inline क्वालीफायर या स्टोरेज क्लास), अनुवाद इकाई में एक परिभाषा होनी चाहिए (कोई फर्क नहीं पड़ता कि अयोग्य है, inline, या extern inline) और इसके लिए बाहरी रूप से दृश्यमान फ़ंक्शन उत्सर्जित किया जाएगा।

एक फंक्शन परिभाषित inline प्रोग्राम में कहीं और उस नाम के साथ पूर्णतया एक फ़ंक्शन की आवश्यकता होती है जिसे या तो परिभाषित किया जाता है extern inline या क्वालीफायर के बिना। यदि पूरे कार्यक्रम में ऐसी एक से अधिक परिभाषाएँ प्रदान की जाती हैं, तो लिंकर डुप्लिकेट प्रतीकों के बारे में शिकायत करेगा। यदि, चूंकि, इसकी कमी है, तो लिंकर जरूरी शिकायत नहीं करता है, क्योंकि यदि सभी उपयोगों को रेखांकित किया जा सकता है, तो इसकी आवश्यकता नहीं है। लेकिन यह शिकायत कर सकता है, क्योंकि कंपाइलर निरंतर इसे अनदेखा कर सकता है inline क्वालीफायर और इसके अतिरिक्त फ़ंक्शन को कॉल उत्पन्न करें, जैसा कि सामान्यतः तब होता है जब कोड को अनुकूलन के बिना संकलित किया जाता है। (यह वांछित व्यवहार हो सकता है, यदि फ़ंक्शन को हर प्रकार से हर जगह रेखांकित किया जाना चाहिए, और यदि ऐसा नहीं है तो एक त्रुटि उत्पन्न होनी चाहिए।) एक सुविधाजनक विधि परिभाषित करना है inline शीर्ष लेख फ़ाइलों में कार्य करता है और प्रति फ़ंक्शन एक .c फ़ाइल बनाता है, जिसमें a extern inline इसके लिए घोषणा और परिभाषा के साथ संबंधित शीर्षलेख फ़ाइल सम्मलित है। इससे कोई फर्क नहीं पड़ता कि घोषणा सम्मलित होने से पहले या पश्चात में है।

अगम्य कोड को अंतिम निष्पादन योग्य में जोड़े जाने से रोकने के लिए यदि किसी फ़ंक्शन के सभी उपयोग इनलाइन किए गए थे, तो यह सलाह दी जाती है[3]ऐसी सभी .c फ़ाइलों की ऑब्जेक्ट फ़ाइलों को एक सिंगल के साथ रखने के लिए extern inline सामान्यतः एक स्थिर पुस्तकालय फ़ाइल में कार्य करता है ar rcs, फिर भिन्न-भिन्न ऑब्जेक्ट फ़ाइलों के अतिरिक्त उस लाइब्रेरी से लिंक करें। यह मात्र उन ऑब्जेक्ट फ़ाइलों को लिंक करने का कारण बनता है जिनकी वास्तव में आवश्यकता होती है, ऑब्जेक्ट फ़ाइलों को सीधे लिंक करने के विपरीत, जिसके कारण उन्हें निरंतर निष्पादन योग्य में सम्मलित किया जाता है। चूंकि, लाइब्रेरी फ़ाइल को लिंकर कमांड लाइन पर अन्य सभी ऑब्जेक्ट फ़ाइलों के पश्चात निर्दिष्ट किया जाना चाहिए, क्योंकि लाइब्रेरी फ़ाइल के पश्चात कार्यों के लिए निर्दिष्ट ऑब्जेक्ट फ़ाइलों से कॉल को लिंकर द्वारा नहीं माना जाएगा। से कॉल करता है inline दूसरे के लिए कार्य करता है inline कार्यों को लिंकर द्वारा स्वचालित रूप से हल किया जाएगा ( s में विकल्प ar rcs यह सुनिश्चित करता है)।

एक वैकल्पिक समाधान लाइब्रेरी के अतिरिक्त लिंक टाइम ऑप्टिमाइज़ेशन का उपयोग करना है। जीसीसी ध्वज प्रदान करता है -Wl,--gc-sections उन अनुभागों को छोड़ने के लिए जिनमें सभी फ़ंक्शन का उपयोग नहीं किया गया है। यह ऑब्जेक्ट फ़ाइलों के स्थितियाँ में होगा जिसमें एक अप्रयुक्त का कोड होगा extern inline फंक्शन। चूंकि, यह अन्य सभी ऑब्जेक्ट फ़ाइलों से किसी भी और सभी अप्रयुक्त अनुभागों को भी हटा देता है, न कि मात्र अप्रयुक्त से संबंधित extern inline कार्य करता है। (फ़ंक्शंस को निष्पादन योग्य में लिंक करना वांछित हो सकता है जिसे प्रोग्रामर द्वारा प्रोग्राम के अतिरिक्त डीबगर से कॉल किया जाना है, उदाहरण के लिए, प्रोग्राम की आंतरिक स्थिति की जांच के लिए।) इस दृष्टिकोण के साथ, यह भी संभव है सभी के साथ एक .c फ़ाइल का उपयोग करने के लिए extern inline प्रति फ़ंक्शन एक .c फ़ाइल के अतिरिक्त कार्य करता है। फिर फाइल को कंपाइल करना होगा -fdata-sections -ffunction-sections. चूंकि, जीसीसी मैनुअल पेज इसके बारे में चेतावनी देता है, कहता है कि ऐसा करने से महत्वपूर्ण लाभ होने पर मात्र इन विकल्पों का उपयोग करें।

कुछ पूरी प्रकार से भिन्न दृष्टिकोण की सलाह देते हैं, जो कि कार्यों को परिभाषित करना है static inline के अतिरिक्त inline हेडर फाइलों में।[2]फिर, कोई अगम्य कोड उत्पन्न नहीं होगा। चूंकि, विपरीत स्थितियाँ में इस दृष्टिकोण में एक खामी है: यदि फ़ंक्शन को एक से अधिक अनुवाद इकाई में इनलाइन नहीं किया जा सकता है तो डुप्लिकेट कोड उत्पन्न होगा। उत्सर्जित फ़ंक्शन कोड को अनुवाद इकाइयों के बीच साझा नहीं किया जा सकता क्योंकि इसके भिन्न-भिन्न पते होने चाहिए। यह एक और कमी है; इस प्रकार के एक फंक्शन का पता लेने के रूप में परिभाषित किया गया है static inline हेडर फ़ाइल में भिन्न-भिन्न अनुवाद इकाइयों में भिन्न-भिन्न मान मिलेंगे। इसलिए, static inline कार्यों का उपयोग मात्र तभी किया जाना चाहिए जब वे मात्र एक अनुवाद इकाई में उपयोग किए जाते हैं, जिसका अर्थ है कि उन्हें मात्र संबंधित .c फ़ाइल में जाना चाहिए, हेडर फ़ाइल में नहीं।

gnu89

gnu89 का शब्दार्थ inline और extern inline अनिवार्य रूप से C99 के पूर्णतया विपरीत हैं,[4] इस अपवाद के साथ कि gnu89 a की पुनर्परिभाषा की अनुमति देता है extern inline एक अयोग्य कार्य के रूप में कार्य करता है, जबकि C99 inline नहीं करता।[5] इस प्रकार, gnu89 extern inline पुनर्परिभाषा के बिना C99 की प्रकार है inline, और ग्नू89 inline C99 की प्रकार है extern inline; दूसरे शब्दों में, gnu89 में, एक फ़ंक्शन परिभाषित किया गया है inline निरंतर होगा और एक फ़ंक्शन परिभाषित किया गया है extern inline बाहरी रूप से दिखाई देने वाले कार्य को कभी भी उत्सर्जित नहीं करेगा। इसके लिए तर्क यह है कि यह वेरिएबल्स से मेल खाता है, जिसके लिए भंडारण को कभी भी आरक्षित नहीं किया जाएगा यदि परिभाषित किया गया हो extern और निरंतर यदि बिना परिभाषित किया गया है। इसके विपरीत, C99 का तर्क यह है कि यदि इसका उपयोग किया जाता है तो यह कम से कम विस्मय का सिद्धांत होगा inline एक साइड-इफ़ेक्ट होगा - निरंतर फ़ंक्शन के एक गैर-इनलाइन संस्करण को उत्सर्जित करने के लिए - जो इसके नाम के विपरीत है।

C99 के लिए इनलाइन फ़ंक्शंस के लिए एक बाहरी रूप से दिखाई देने वाला फ़ंक्शन उदाहरण प्रदान करने की आवश्यकता के बारे में और अगम्य कोड के साथ परिणामी समस्या के बारे में टिप्पणी, यथोचित परिवर्तनों के साथ-साथ gnu89 पर भी लागू होती है।

जीसीसी तक और संस्करण 4.2 सहित gnu89 का उपयोग किया inline शब्दार्थ तब भी जब -std=c99 स्पष्ट रूप से निर्दिष्ट किया गया था।[6] संस्करण 5 के साथ,[5]Gcc ने gnu89 से gnu11 बोली में स्विच किया, प्रभावी रूप से C99 को सक्षम किया inline डिफ़ॉल्ट रूप से शब्दार्थ। इसके अतिरिक्त gnu89 शब्दार्थ का उपयोग करने के लिए, उन्हें या तो स्पष्ट रूप से सक्षम करना होगा -std=gnu89 या, मात्र इनलाइनिंग को प्रभावित करने के लिए, -fgnu89-inline, या जोड़कर gnu_inline सभी के लिए विशेषता inline घोषणाएं। C99 शब्दार्थ सुनिश्चित करने के लिए, या तो -std=c99, -std=c11, -std=gnu99 या -std=gnu11 (बिना -fgnu89-inline) उपयोग किया जा सकता है।[3]


सी ++

सी ++ में, एक फ़ंक्शन परिभाषित किया गया है inline यदि आवश्यक हो, तो अनुवाद इकाइयों के बीच साझा किए गए फ़ंक्शन का उत्सर्जन करेगा, सामान्यतः इसे ऑब्जेक्ट फ़ाइल के सामान्य अनुभाग में डालकर जिसके लिए इसकी आवश्यकता होती है। फ़ंक्शन की हर जगह एक ही परिभाषा होनी चाहिए, निरंतर के साथ inline क्वालीफायर। सी ++ में, extern inline वैसा ही है जैसा कि inline. सी ++ दृष्टिकोण के लिए तर्क यह है कि यह प्रोग्रामर के लिए सबसे सुविधाजनक विधि है, क्योंकि अगम्य कोड को हटाने के लिए कोई विशेष सावधानी नहीं बरती जानी चाहिए और सामान्य कार्यों की प्रकार, इससे कोई फर्क नहीं पड़ता कि क्या extern निर्दिष्ट है या नहीं। inline ई> क्वालीफायर स्वचालित रूप से एक वर्ग परिभाषा के हिस्से के रूप में परिभाषित फ़ंक्शन में जोड़ा जाता है।

आर्मसीसी

C90 मोड में armcc प्रदान करता है extern inline और inline सिमेंटिक्स जो सी ++ के समान हैं: यदि आवश्यक हो तो ऐसी परिभाषाएं अनुवाद इकाइयों के बीच साझा किए गए फ़ंक्शन को छोड़ देंगी। C99 मोड में, extern inline निरंतर एक फ़ंक्शन का उत्सर्जन करता है, लेकिन सी ++ की प्रकार, इसे अनुवाद इकाइयों के बीच साझा किया जाएगा। इस प्रकार, समान कार्य को परिभाषित किया जा सकता है extern inline विभिन्न अनुवाद इकाइयों में।[7] यह यूनिक्स सी कंपाइलर्स के पारंपरिक व्यवहार से मेल खाता है[8] एकाधिक गैर के लिएextern अप्रारंभीकृत वैश्विक चर की परिभाषाएँ।

प्रतिबंध

एक का पता लेना inline फ़ंक्शन को किसी भी स्थितियाँ में उस फ़ंक्शन की गैर-रेखांकित प्रतिलिपि के लिए कोड की आवश्यकता होती है।

C99 में, ए inline या extern inline फंक्शन का उपयोग नहीं करना चाहिए static वैश्विक चर या गैर परिभाषितconst static स्थानीय चर। const static स्थानीय चर भिन्न-भिन्न अनुवाद इकाइयों में भिन्न-भिन्न ऑब्जेक्ट हो सकते हैं या नहीं भी हो सकते हैं, यह इस बात पर निर्भर करता है कि फ़ंक्शन इनलाइन था या कॉल किया गया था या नहीं। मात्र static inline परिभाषाएँ पहचानकर्ताओं को बिना किसी प्रतिबंध के आंतरिक लिंकेज के साथ संदर्भित कर सकती हैं; वे प्रत्येक अनुवाद इकाई में भिन्न-भिन्न वस्तुएँ होंगी। सी ++ में, दोनों const और गैर-const static स्थानीय लोगों को अनुमति है और वे सभी अनुवाद इकाइयों में एक ही वस्तु का उल्लेख करते हैं।

जीसीसी कार्यों को इनलाइन नहीं कर सकता है यदि[3]# वे विविध कार्य हैं,

  1. उपयोग alloca
  2. गणना का उपयोग करें goto
  3. नॉनलोकल का उपयोग करें goto
  4. नेस्टेड फंक्शन का उपयोग करें
  5. उपयोग setjmp
  6. उपयोग __builtin_longjmp
  7. उपयोग __builtin_return, या
  8. उपयोग __builtin_apply_args

एमएसडीएन पर माइक्रोसॉफ्ट विनिर्देशों के आधार पर, एमएस विज़ुअल सी ++ इनलाइन नहीं कर सकता (यहां तक ​​​​कि नहीं __forceinline), यदि

  1. फ़ंक्शन या उसके कॉलर को /Ob0 (डीबग बिल्ड के लिए डिफ़ॉल्ट विकल्प) के साथ संकलित किया गया है।
  2. फ़ंक्शन और कॉलर विभिन्न प्रकार के अपवाद हैंडलिंग (एक में C ++ अपवाद हैंडलिंग, दूसरे में संरचित अपवाद हैंडलिंग) का उपयोग करते हैं।
  3. फ़ंक्शन में एक चर तर्क सूची है।
  4. फ़ंक्शन इनलाइन असेंबली का उपयोग करता है, जब तक कि /Og, /Ox, /O1, या /O2 के साथ संकलित न हो।
  5. फ़ंक्शन रिकर्सन (कंप्यूटर विज्ञान) है और इसके साथ नहीं है #pragma inline_recursion(on). प्रागमा के साथ, पुनरावर्ती कार्यों को 16 कॉल की डिफ़ॉल्ट गहराई में रेखांकित किया गया है। इनलाइनिंग गहराई को कम करने के लिए, उपयोग करें inline_depth pragma.
  6. फ़ंक्शन आभासी फंक्शन है और इसे वस्तुतः कहा जाता है। आभासी कार्यों के लिए सीधी कॉल को इनलाइन किया जा सकता है।
  7. प्रोग्राम फ़ंक्शन का पता लेता है और फ़ंक्शन को पॉइंटर के माध्यम से कॉल किया जाता है। उन कार्यों के लिए सीधी कॉल जिनका पता लिया जा चुका है, को इनलाइन किया जा सकता है।
  8. फंक्शन को नग्न के साथ भी चिह्नित किया गया है __declspec संशोधक।

समस्याएं

सामान्य रूप से इनलाइन विस्तार की समस्याओं के अतिरिक्त (देखें Inline expansion § Effect on performance), inline कई कारणों से एक भाषा सुविधा के रूप में कार्य उतने मूल्यवान नहीं हो सकते जितने वे दिखाई देते हैं:

  • अधिकांशतः, एक कंपाइलर यह तय करने के लिए मानव की तुलना में उत्तम स्थिति में होता है कि किसी विशेष फ़ंक्शन को इनलाइन किया जाना चाहिए या नहीं। कभी-कभी संकलक उतने कार्यों को इनलाइन करने में सक्षम नहीं हो सकता जितना प्रोग्रामर इंगित करता है।
  • ध्यान देने वाली एक महत्वपूर्ण बात यह है कि कोड (का inline function) अपने क्लाइंट (कॉलिंग फ़ंक्शन) के सामने आ जाता है।
  • जैसे-जैसे कार्य विकसित होते हैं, वे इनलाइनिंग के लिए उपयुक्त हो सकते हैं जहां वे पहले नहीं थे, या जहां वे पहले थे वहां इनलाइनिंग के लिए अब उपयुक्त नहीं हैं। किसी फ़ंक्शन को इनलाइन या अन-इनलाइन करते समय मैक्रोज़ में कनवर्ट करने से आसान होता है, फिर भी इसे अतिरिक्त रखरखाव की आवश्यकता होती है जो सामान्यतः अपेक्षाकृत कम लाभ देती है।
  • देशी सी-आधारित संकलन प्रणालियों में प्रसार में उपयोग किए जाने वाले इनलाइन फ़ंक्शंस संकलन समय को बढ़ा सकते हैं, क्योंकि उनके बॉडी के मध्यवर्ती प्रतिनिधित्व को प्रत्येक कॉल साइट में कॉपी किया जाता है।
  • की विशिष्टता inline सी 99 में फ़ंक्शन की पूर्णतया एक बाहरी परिभाषा की आवश्यकता होती है, यदि इसे कहीं उपयोग किया जाता है। यदि प्रोग्रामर द्वारा ऐसी परिभाषा प्रदान नहीं की गई है, तो इससे आसानी से लिंकर त्रुटियां हो सकती हैं। यह ऑप्टिमाइज़ेशन बंद होने के साथ हो सकता है, जो सामान्यतः इनलाइनिंग को रोकता है। दूसरी ओर, परिभाषाओं को जोड़ना अगम्य कोड का कारण बन सकता है यदि प्रोग्रामर सावधानी से इसे टालता नहीं है, लिंक करने के लिए उन्हें लाइब्रेरी में डालकर, लिंक टाइम ऑप्टिमाइज़ेशन का उपयोग करके, या static inline.
  • C++ में, a को परिभाषित करना आवश्यक है inline इसका उपयोग करने वाले प्रत्येक मॉड्यूल (अनुवाद इकाई) में कार्य करता है, जबकि एक सामान्य कार्य को मात्र एक मॉड्यूल में परिभाषित किया जाना चाहिए। अन्यथा अन्य सभी मॉड्यूलों से स्वतंत्र रूप से एक मॉड्यूल को संकलित करना संभव नहीं होगा। कंपाइलर के आधार पर, यह प्रत्येक संबंधित ऑब्जेक्ट फ़ाइल को प्रत्येक मॉड्यूल के लिए फ़ंक्शन के कोड की प्रतिलिपि रखने का कारण बन सकता है, जो इनलाइन नहीं किया जा सका।
  • उपकरणों के नियंत्रण के लिए सॉफ्टवेयर में, प्रागमा स्टेटमेंट्स जैसे विशेष संकलक निर्देशों के उपयोग द्वारा अधिकांशतः कुछ कार्यों को कुछ कोड अनुभागों में रखने की आवश्यकता होती है। कभी-कभी, एक मेमोरी सेगमेंट में एक फ़ंक्शन को किसी अन्य मेमोरी सेगमेंट में फ़ंक्शन को कॉल करने की आवश्यकता हो सकती है, और यदि कॉल किए गए फ़ंक्शन की इनलाइनिंग होती है, तो कॉल किए गए फ़ंक्शन का कोड उस सेगमेंट में समाप्त हो सकता है जहां यह नहीं होना चाहिए। उदाहरण के लिए, उच्च-प्रदर्शन स्मृति खंड कोड स्थान में बहुत सीमित हो सकते हैं, और यदि ऐसे स्थान से संबंधित कोई फ़ंक्शन किसी अन्य बड़े फ़ंक्शन को कॉल करता है जो उच्च-प्रदर्शन अनुभाग में नहीं है और कहा गया फ़ंक्शन अनुपयुक्त रूप से इनलाइन हो जाता है, तो इससे उच्च-प्रदर्शन स्मृति खंड कोड स्थान से बाहर हो सकता है। इस कारण से, कभी-कभी यह सुनिश्चित करना आवश्यक होता है कि फ़ंक्शन इनलाइन न हो जाएं।

उद्धरण

एक फंक्शन घोषणा [। . . ] एक इनलाइन विनिर्देशक के साथ एक इनलाइन फ़ंक्शन घोषित करता है। इनलाइन विनिर्देशक कार्यान्वयन को इंगित करता है कि कॉल के बिंदु पर फ़ंक्शन बॉडी के इनलाइन प्रतिस्थापन को सामान्य फ़ंक्शन कॉल तंत्र के लिए प्राथमिकता दी जानी चाहिए। कॉल के बिंदु पर इस इनलाइन प्रतिस्थापन को करने के लिए कार्यान्वयन की आवश्यकता नहीं है; चूंकि, यदि यह इनलाइन प्रतिस्थापन छोड़ दिया गया हो, 7.1.2 द्वारा परिभाषित इनलाइन फ़ंक्शंस के अन्य नियमों का अभी भी सम्मान किया जाएगा।
— ISO/IEC 14882:2011, वर्तमान C++ मानक, खंड 7.1.2
एक इनलाइन फ़ंक्शन विनिर्देशक के साथ घोषित एक फ़ंक्शन एक इनलाइन फ़ंक्शन है। [ . . . ] किसी फ़ंक्शन को इनलाइन फ़ंक्शन बनाने से पता चलता है कि फ़ंक्शन को जितनी जल्दी हो सके कॉल करें। जिस हद तक ऐसे सुझाव प्रभावी हैं, वह कार्यान्वयन-परिभाषित है (फुटनोट: उदाहरण के लिए, एक कार्यान्वयन इनलाइन प्रतिस्थापन कभी नहीं कर सकता है, या मात्र इनलाइन प्रतिस्थापन इनलाइन घोषणा के दायरे में कॉल करने के लिए कर सकता है।)
[ . . . ] एक इनलाइन परिभाषा फ़ंक्शन के लिए बाहरी परिभाषा प्रदान नहीं करती है, और किसी अन्य अनुवाद इकाई (प्रोग्रामिंग) में बाहरी परिभाषा को प्रतिबंधित नहीं करती है। एक इनलाइन परिभाषा एक बाहरी परिभाषा के लिए एक विकल्प प्रदान करती है, जिसका उपयोग अनुवादक उसी अनुवाद इकाई में फ़ंक्शन के लिए किसी कॉल को लागू करने के लिए कर सकता है। यह निर्दिष्ट नहीं है कि फ़ंक्शन के लिए कॉल इनलाइन परिभाषा या बाहरी परिभाषा का उपयोग करता है या नहीं।
— ISO 9899:1999(E), C99 मानक, खंड 6.7.4

यह भी देखें

संदर्भ

  1. 1.0 1.1 Meyers, Randy (July 1, 2002). "The New C: Inline Functions". {{cite journal}}: Cite journal requires |journal= (help)
  2. 2.0 2.1 "Inline Functions in C".
  3. 3.0 3.1 3.2 3.3 "Using the GNU Compiler Collection (GCC): Inline".
  4. "Josef "Jeff" Sipek » GNU inline vs. C99 inline".
  5. 5.0 5.1 "Porting to GCC 5 - GNU Project".
  6. "Ian Lance Taylor - Clean up extern inline".
  7. "Documentation – Arm Developer".
  8. gcc manual page, description of -fno-common


बाहरी संबंध