6.7.4 फ़ंक्शन विनिर्देशक
C99 की एक नई सुविधा:inline
कीवर्ड, सी से अनुकूलित ++, एक है समारोह-विनिर्देशक है कि केवल समारोह घोषणाओं में इस्तेमाल किया जा सकता। यह प्रोग्राम ऑप्टिमाइज़ेशन के लिए उपयोगी है जिसे कॉल की साइट पर दिखाई देने वाली फ़ंक्शन की परिभाषा की आवश्यकता होती है। (ध्यान दें कि मानक इन अनुकूलन की प्रकृति को निर्दिष्ट करने का प्रयास नहीं करता है।)
यदि फ़ंक्शन में आंतरिक लिंकेज है, या यदि उसके पास बाहरी लिंकेज है, तो दृश्यता सुनिश्चित है और कॉल बाहरी परिभाषा के समान अनुवाद इकाई में है। इन मामलों में, inline
फ़ंक्शन की घोषणा या परिभाषा में कीवर्ड की मौजूदगी का इस
बात पर कोई प्रभाव नहीं पड़ता है कि वरीयता के संकेत से परे उस फ़ंक्शन के कॉल को inline
कीवर्ड के बिना घोषित किए गए अन्य फ़ंक्शन के कॉल के लिए प्राथमिकता दी जानी चाहिए ।
दृश्यता बाहरी लिंकेज के साथ एक फ़ंक्शन के कॉल के लिए एक समस्या है जहां कॉल फ़ंक्शन की परिभाषा से एक अलग अनुवाद इकाई में है। इस स्थिति में, inline
कीवर्ड अनुवाद इकाई को कॉल करने की अनुमति देता है जिसमें फ़ंक्शन की परिभाषा, स्थानीय या इनलाइन भी होती है।
एक प्रोग्राम में एक बाहरी परिभाषा के साथ एक अनुवाद इकाई, एक इनलाइन परिभाषा के साथ एक अनुवाद इकाई और एक घोषणा के साथ एक अनुवाद इकाई हो सकती है, लेकिन एक फ़ंक्शन के लिए कोई परिभाषा नहीं होती है। बाद की अनुवाद इकाई में कॉल बाहरी परिभाषा का हमेशा की तरह उपयोग करेगी।
किसी फ़ंक्शन की इनलाइन परिभाषा को बाहरी परिभाषा की तुलना में एक अलग परिभाषा माना जाता है। यदि func
बाहरी लिंकेज के साथ कुछ फ़ंक्शन के लिए कॉल होता है जहां एक इनलाइन परिभाषा दिखाई देती है, तो व्यवहार वैसा ही होता है जैसे कि कॉल किसी अन्य फ़ंक्शन के लिए किया गया था, कहते हैं
__func
, आंतरिक लिंकेज के साथ। एक अनुरूपता कार्यक्रम पर निर्भर नहीं होना चाहिए कि कौन सा फ़ंक्शन कहा जाता है। यह मानक में इनलाइन मॉडल है।
एक अनुरूप कार्यक्रम इनलाइन परिभाषा का उपयोग करके कार्यान्वयन पर निर्भर नहीं होना चाहिए, न ही यह बाहरी परिभाषा का उपयोग करके कार्यान्वयन पर भरोसा कर सकता है। किसी फ़ंक्शन का पता हमेशा बाहरी परिभाषा के अनुरूप पता होता है, लेकिन जब यह पता फ़ंक्शन को कॉल करने के लिए उपयोग किया जाता है, तो इनलाइन परिभाषा का उपयोग किया जा सकता है। इसलिए, निम्न उदाहरण अपेक्षित रूप से व्यवहार नहीं कर सकता है।
inline const char *saddr(void)
{
static const char name[] = "saddr";
return name;
}
int compare_name(void)
{
return saddr() == saddr(); // unspecified behavior
}
चूंकि कार्यान्वयन कॉल में से एक के लिए इनलाइन परिभाषा का उपयोग कर सकता है saddr
और दूसरे के लिए बाहरी परिभाषा का उपयोग कर सकता है, समानता ऑपरेशन 1 (सच) का मूल्यांकन करने की गारंटी नहीं है। इससे पता चलता है कि इनलाइन परिभाषा के भीतर परिभाषित स्थिर वस्तुएं बाहरी परिभाषा में अपनी संबंधित वस्तु से अलग हैं। इसने const
इस प्रकार की एक गैर- वस्तु को परिभाषित करने के खिलाफ बाधा को भी प्रेरित किया ।
इनलाइनिंग को मानक में इस तरह से जोड़ा गया था कि इसे मौजूदा लिंकर तकनीक के साथ लागू किया जा सके, और C99 इनलाइनिंग का एक उपसमूह C ++ के साथ संगत है। यह आवश्यक है कि इनलाइन फ़ंक्शन की परिभाषा वाले एक अनुवाद इकाई को फ़ंक्शन के लिए बाहरी परिभाषा प्रदान करने वाले के रूप में निर्दिष्ट किया जाए। क्योंकि उस विनिर्देश में केवल एक घोषणा होती है जिसमें या तो inline
कीवर्ड की कमी होती है , या जिसमें दोनों होते हैं inline
और extern
यह C ++ अनुवादक द्वारा भी स्वीकार किया जाएगा।
C99 में Inlining दो तरीकों से C ++ विनिर्देशन का विस्तार करता है। सबसे पहले, यदि कोई कार्य inline
एक अनुवाद इकाई में घोषित किया जाता है, तो
उसे inline
हर दूसरी अनुवाद इकाई में घोषित करने की आवश्यकता नहीं है । यह अनुमति देता है, उदाहरण के लिए, एक लाइब्रेरी फ़ंक्शन जिसे लाइब्रेरी के भीतर इनलाइन किया जाना है, लेकिन केवल एक बाहरी परिभाषा के माध्यम से कहीं और उपलब्ध है। बाहरी फ़ंक्शन के लिए आवरण फ़ंक्शन का उपयोग करने के विकल्प के लिए एक अतिरिक्त नाम की आवश्यकता होती है; और यह भी प्रतिकूल प्रभाव प्रदर्शन कर सकते हैं अगर एक अनुवादक वास्तव में इनलाइन प्रतिस्थापन नहीं करता है।
दूसरा, एक इनलाइन फ़ंक्शन की सभी परिभाषाएँ "बिल्कुल समान" होने की आवश्यकता को इस आवश्यकता से बदल दिया जाता है कि प्रोग्राम का व्यवहार इस बात पर निर्भर नहीं होना चाहिए कि क्या एक दृश्य इनलाइन परिभाषा के साथ लागू किया गया है, या बाहरी परिभाषा, समारोह। यह एक इनलाइन परिभाषा को एक विशेष अनुवाद इकाई के भीतर इसके उपयोग के लिए विशेषीकृत करने की अनुमति देता है। उदाहरण के लिए, किसी लाइब्रेरी फ़ंक्शन की बाहरी परिभाषा में कुछ तर्क सत्यापन शामिल हो सकते हैं जो उसी लाइब्रेरी में अन्य फ़ंक्शन से किए गए कॉल के लिए आवश्यक नहीं हैं। ये एक्सटेंशन कुछ फायदे प्रदान करते हैं; और प्रोग्रामर जो संगतता के बारे में चिंतित हैं, वे सख्त सी ++ नियमों का पालन कर सकते हैं।
ध्यान दें कि मानक हेडर में मानक पुस्तकालय कार्यों की इनलाइन परिभाषा प्रदान करने के लिए कार्यान्वयन के लिए यह उचित नहीं है क्योंकि यह कुछ विरासत कोड को तोड़ सकता है जो मानक पुस्तकालय कार्यों को उनके हेडर सहित शामिल करने के बाद पुनः परिभाषित करता है। inline
कीवर्ड केवल कार्यों को इनलाइन करने का सुझाव देने के लिए एक पोर्टेबल तरीके के साथ उपयोगकर्ताओं को प्रदान करने का इरादा है। क्योंकि मानक शीर्षकों को पोर्टेबल होने की आवश्यकता नहीं है, कार्यान्वयन में अन्य विकल्प हैं:
#define abs(x) __builtin_abs(x)
या अन्य गैर-पोर्टेबल तंत्र मानक पुस्तकालय कार्यों को इनलाइन करने के लिए।