जवाबों:
inline
संकलक को निर्देश देता है कि वास्तविक कॉल को निष्पादित करने के बजाय फ़ंक्शन सामग्री को कॉलिंग कोड में एम्बेड करने का प्रयास करें।
छोटे कार्यों के लिए जिन्हें अक्सर कहा जाता है जो एक बड़ा प्रदर्शन अंतर बना सकते हैं।
हालाँकि, यह केवल एक "संकेत" है, और संकलक इसे अनदेखा कर सकता है, और अधिकांश संकलक अनुकूलन के भाग के रूप में भी, जब कीवर्ड संभव नहीं है, तो "इनलाइन" करने का प्रयास करेंगे।
उदाहरण के लिए:
static int Inc(int i) {return i+1};
.... // some code
int i;
.... // some more code
for (i=0; i<999999; i = Inc(i)) {/*do something here*/};
यह तंग लूप प्रत्येक पुनरावृत्ति पर एक फ़ंक्शन कॉल करेगा, और फ़ंक्शन सामग्री वास्तव में उस कोड की तुलना में काफी कम है, जिसे कंपाइलर को कॉल करने के लिए डालने की आवश्यकता है। inline
अनिवार्य रूप से संकलक को निर्देश देगा कि वह कोड को एक समकक्ष में बदले:
int i;
....
for (i=0; i<999999; i = i+1) { /* do something here */};
वास्तविक फ़ंक्शन कॉल को छोड़ना और वापस आना
जाहिर है कि यह एक उदाहरण है बिंदु को दिखाने के लिए, कोड का एक वास्तविक टुकड़ा नहीं।
static
गुंजाइश को संदर्भित करता है। सी में इसका मतलब है कि फ़ंक्शन / चर का उपयोग केवल उसी अनुवाद इकाई के भीतर किया जा सकता है।
static
(साथ या बिना inline
) हेडर में पूरी तरह से अच्छी तरह से हो सकता है, बिना कारण देखें। टेम्प्लेट C ++ के लिए है, यह प्रश्न C. के बारे में है
inline
से चिन्हित करना अच्छी शैली है, इमो
inline
नहीं देता है कि वह इनलाइनिंग में कोई प्रयास न करे। यह केवल प्रोग्रामर को ओडीआर उल्लंघन के बिना कई अनुवाद इकाइयों में फ़ंक्शन बॉडी को शामिल करने देता है। इसका एक पक्ष प्रभाव यह है कि यह संकलक के लिए संभव बनाता है, जब यह फ़ंक्शन को इनलाइन करता है, वास्तव में ऐसा करने के लिए।
डिफ़ॉल्ट रूप से, इनलाइन परिभाषा केवल वर्तमान अनुवाद इकाई में मान्य है।
यदि संग्रहण वर्ग है extern
, तो पहचानकर्ता के पास बाहरी लिंकेज है और इनलाइन परिभाषा बाहरी परिभाषा भी प्रदान करती है।
यदि संग्रहण वर्ग है static
, तो पहचानकर्ता के पास आंतरिक लिंकेज है और इनलाइन परिभाषा अन्य अनुवाद इकाइयों में अदृश्य है।
यदि संग्रहण वर्ग अनिर्दिष्ट है, तो इनलाइन परिभाषा केवल वर्तमान अनुवाद इकाई में दिखाई देती है, लेकिन पहचानकर्ता के पास अभी भी बाहरी लिंकेज है और एक अलग अनुवाद इकाई में एक बाहरी परिभाषा प्रदान की जानी चाहिए। संकलक या तो इनलाइन या बाहरी परिभाषा का उपयोग करने के लिए स्वतंत्र है यदि फ़ंक्शन को वर्तमान अनुवाद इकाई के भीतर कहा जाता है।
जैसा कि संकलक इनलाइन (और इनलाइन नहीं) के लिए स्वतंत्र है, जिसकी परिभाषा वर्तमान अनुवाद इकाई में दिखाई देती है (और, लिंक-टाइम अनुकूलन के लिए धन्यवाद, यहां तक कि विभिन्न अनुवाद इकाइयों में भी, हालांकि सी मानक वास्तव में खाता नहीं है वह), अधिकांश व्यावहारिक उद्देश्यों के लिए, static
और static inline
फ़ंक्शन परिभाषाओं के बीच कोई अंतर नहीं है ।
inline
विनिर्देशक (जैसे register
भंडारण वर्ग) केवल एक संकलक संकेत है, और संकलक पूरी तरह से इसे अनदेखा करने के लिए स्वतंत्र है। मानकों का पालन करने वाले गैर-अनुकूलन वाले कंपाइलरों को केवल उनके दुष्प्रभावों का सम्मान करना पड़ता है, और संकलक का अनुकूलन इन संकेतों को स्पष्ट संकेतों के साथ या बिना करेगा।
inline
और register
बेकार नहीं हैं, हालांकि, जब वे प्रोग्रामर कोड लिखने वाले त्रुटियों को फेंकने के लिए कंपाइलर को निर्देश देते हैं, जो अनुकूलन को असंभव बना देगा: एक inline
आंतरिक परिभाषा आंतरिक लिंकेज के साथ पहचानकर्ताओं का संदर्भ नहीं दे सकती है (क्योंकि ये एक अलग अनुवाद इकाई में अनुपलब्ध होगा) या स्थैतिक भंडारण अवधि के साथ परिवर्तनीय स्थानीय चर को परिभाषित करें (जैसा कि ये राज्य अनुवाद इकाइयों को साझा नहीं करेंगे), और आप register
-qualified चर के पते नहीं ले सकते ।
व्यक्तिगत रूप से, मैं सम्मेलन का उपयोग static
हेडर के भीतर फ़ंक्शन परिभाषाओं को चिह्नित करने के लिए भी करता हूं inline
, क्योंकि हेडर फ़ाइलों में फ़ंक्शन परिभाषाओं को डालने का मुख्य कारण उन्हें निष्प्रभावी बनाना है।
सामान्य तौर पर, मैं केवल हेडर के भीतर घोषणाओं के अलावा static inline
फ़ंक्शन और static const
ऑब्जेक्ट परिभाषाओं का उपयोग करता हूं extern
।
मैंने कभी भी inline
स्टोरेज क्लास से अलग एक फंक्शन नहीं लिखा है static
।
inline
में बात करना जैसे कि यह वास्तव में इनलाइनिंग लागू किया गया है भ्रामक और यकीनन गलत है। कोई भी आधुनिक संकलक इसे एक इनलाइन के संकेत के रूप में उपयोग नहीं करता है या किसी फ़ंक्शन की इनलाइनिंग को सक्षम करने के लिए इसकी आवश्यकता होती है।
static
और static inline
। ये दोनों अन्य अनुवाद इकाइयों के लिए परिभाषा को अदृश्य बनाते हैं। तो static inline
इसके बजाय लिखने का एक समझदार कारण क्या होगा static
?
जीसीसी के साथ अपने अनुभव से मुझे पता है कि static
और static inline
एक तरह से अलग है कि संकलित अप्रयुक्त कार्यों के बारे में चेतावनी कैसे जारी करता है। अधिक सटीक जब आप static
फ़ंक्शन की घोषणा करते हैं और इसका उपयोग वर्तमान अनुवाद इकाई में नहीं किया जाता है तो संकलक अप्रयुक्त फ़ंक्शन के बारे में चेतावनी का उत्पादन करता है, लेकिन आप इसे बदलने के साथ उस चेतावनी को रोक सकते हैं static inline
।
इस प्रकार मुझे लगता है कि static
अनुवाद इकाइयों में इस्तेमाल किया जाना चाहिए और अतिरिक्त चेक कंपाइलर से लाभ का उपयोग अप्रयुक्त कार्यों को खोजने के लिए किया जाता है। और static inline
चेतावनी जारी किए बिना फ़ंक्शंस (बाहरी लिंकेज की अनुपस्थिति के कारण) हो सकने वाले कार्य प्रदान करने के लिए हेडर फ़ाइलों में उपयोग किया जाना चाहिए।
दुर्भाग्य से मुझे उस तर्क के लिए कोई सबूत नहीं मिला। यहां तक कि जीसीसी प्रलेखन से मैं यह निष्कर्ष निकालने में सक्षम नहीं था कि inline
अप्रयुक्त फ़ंक्शन चेतावनियों को रोकता है। अगर किसी का वर्णन करने के लिए लिंक साझा करेंगे, तो मैं सराहना करूँगा।
warning: unused function 'function' [clang-diagnostic-unused-function]
एक static inline
फ़ंक्शन के लिए मिला जब clang-tidy
(v8.0.1) के साथ निर्माण किया गया, जिसका उपयोग किसी अन्य अनुवाद इकाई में किया जाता है। लेकिन निश्चित रूप से, यह सबसे अच्छा स्पष्टीकरण और संयोजन के लिए कारण में से एक है static
और inline
!
C में, static
आपके द्वारा परिभाषित फंक्शन या वैरिएबल का उपयोग केवल इस फ़ाइल में किया जा सकता है (अर्थात संकलन इकाई)
तो, static inline
इनलाइन फ़ंक्शन का मतलब है जो केवल इस फ़ाइल में उपयोग किया जा सकता है।
संपादित करें:
संकलन इकाई का अनुवाद इकाई होना चाहिए
the compile unit
है कि कुछ ऐसा है जो मैंने गलती से लिखा है, ऐसी कोई बात नहीं है, वास्तविक शब्दावली हैtranslation unit
एक अंतर जो भाषा के स्तर पर नहीं है, लेकिन लोकप्रिय कार्यान्वयन स्तर है: जीसीसी के कुछ संस्करण static inline
डिफ़ॉल्ट रूप से आउटपुट से अपरिष्कृत कार्यों को हटा देंगे , लेकिन static
अपरिवर्तित होने पर भी सादे कार्यों को रखेंगे । मुझे यकीन है कि जो संस्करण इस पर लागू होता है नहीं कर रहा हूँ, लेकिन एक व्यावहारिक दृष्टिकोण से यह यह एक अच्छा विचार करने के लिए हमेशा उपयोग किया जा सकता है इसका मतलब inline
के लिए static
हेडर में कार्य करता है।
inline
परिभाषा में उपयोग के बारे में क्या ? क्या आप भी extern
कार्यों के लिए इसका इस्तेमाल नहीं करते हैं ?
attribute((used))
और इसके उपयोग को अन्यथा असंबद्ध static
कार्यों और डेटा को संदर्भित करने की अनुमति देता है ।
static
गुंजाइश को संदर्भित करता है। सी में इसका मतलब है कि फ़ंक्शन / चर का उपयोग केवल उसी अनुवाद इकाई के भीतर किया जा सकता है।