2012-02-24 27 views
20

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

मैं जानता हूँ कि यह सामान्य बुरा व्यवहार में है हेडर में कार्यों को परिभाषित करने के लिए। आपको इसका उल्लेख नहीं करना है कि उत्तर में, यह प्रश्न तकनीकी रूप से है।

+1

** ** उन्हें ** हेडर में लागू करने के लिए बुरा है, उन्हें परिभाषित नहीं करना;) – m0skit0

+0

सी/सी ++ में हेडर फ़ाइल का विचार डेवलपर्स के लिए अतिरिक्त काम करता है, मुझे समझ में आता है कि कोई भी घोषणा आकार को दोहराना नहीं चाहता – linquize

+1

कोड आकार में छोटा या यह क्या करता है में छोटा: डी? – UmNyobe

उत्तर

22

मैं static inline का उपयोग करता हूं, लेकिन static भी काम करेगा।

extern और extern inline बाहर हैं क्योंकि आप एक से अधिक बाहरी परिभाषाओं अगर हैडर एक से अधिक अनुवाद इकाई में शामिल है मिल चाहते हैं, तो आप static, static inline और inline विनिर्देश पर विचार करने की जरूरत है।

हेप्टिक सही ढंग से अपने उत्तर में बताता है कि अधिकांश कंपेलर inline निर्दिष्ट किए गए हैं या नहीं, भले ही inline का मुख्य प्रभाव जुड़ाव पर इसका प्रभाव है।

हालांकि, static परिभाषाओं में आंतरिक संबंध है, इसलिए static और static inline के बीच बहुत अंतर नहीं है; मैं पूरी तरह से स्टाइलिस्ट कारणों के लिए हेडर फ़ाइलों में फ़ंक्शन परिभाषाओं के लिए static inline पसंद करता हूं (अंगूठे का नियम: हेडर फ़ाइलों में केवल extern घोषणाएं, static const चर परिभाषाएं और static inline फ़ंक्शन परिभाषाएं होनी चाहिए)।

inlinestatic बिना या extern परिणाम एक इनलाइन परिभाषा, जो मानक राज्यों (C99 6.7.4, §6)

में एक बाहरी परिभाषा है, जो एक अनुवादक के लिए उपयोग कर सकते हैं के लिए एक विकल्प प्रदान करता है को उसी अनुवाद इकाई में फ़ंक्शन पर कोई भी कॉल लागू करें। यह निर्दिष्ट नहीं है कि फ़ंक्शन पर कॉल इनलाइन परिभाषा या बाहरी परिभाषा का उपयोग करता है।

यानी इनलाइन परिभाषाओं को हमेशा बाहरी परिभाषाओं के साथ होना चाहिए, जो आप खोज रहे हैं।

C99 इनलाइन अर्थ विज्ञान की बारीकियों के बारे में कुछ अधिक जानकारी this answer में पाया जा सकता, Clang homepage और C99 Rationale (PDF) पर।

ध्यान रखें कि जीसीसी केवल C99 अर्थ विज्ञान का उपयोग करेगा अगर -std=c99 या -std=gnu99 मौजूद है रखें ...

+0

@ हेप्टिक: मानक का शब्द कुछ हद तक संदिग्ध है, लेकिन जैसा कि मैं इसे समझता हूं, संकलक हमेशा किसी भी इनलाइन परिभाषा को पूरी तरह से अनदेखा करने के लिए स्वतंत्र होता है और बाहरी पर वापस आ जाता है, जो स्पष्ट रूप से विफल हो जाता है यदि ऐसी परिभाषा नहीं है एक और अनुवाद इकाई में ... – Christoph

+0

@ हेप्टिक: मेरी व्याख्या सही प्रतीत होती है - साथ में उदाहरण देखें, यानी सी 99 7.6.4 §8 – Christoph

+0

@ हेप्टिक: भी, सभी प्रमुख कंपाइलर्स/लिंकर आपके द्वारा वर्णित तरीके से काम नहीं करते - इसके अतिरिक्त clang करने के लिए, gcc भी c99 semantics का सम्मान करता है अगर '-std = c99' या' -std = gnu99' मौजूद है ... – Christoph

0

मुझे लगता है कि स्थिर इनलाइन कार्यों आप इनलाइन करना चाहते हैं के लिए जाने का रास्ता है, और केवल स्थिर उन लोगों के लिए आप नहीं करना चाहती।

स्थिर दृश्यता को संदर्भित करता है, लेकिन इनलाइन मानक (C99) में दृश्यता के बारे में अस्पष्ट है। वैसे भी, यह इसका उद्देश्य नहीं है: इनलाइन इनलाइनिंग फ़ंक्शंस के लिए है, इस प्रकार इसका एक दृश्यता बिंदु से दुष्प्रभाव होता है जिसे आप नहीं चाहते हैं।

+0

आपने व्याख्या करने की उपेक्षा क्यों की। –

+0

"इनलाइन अस्पष्ट है और आपके उद्देश्य को हराकर बाहरी कीवर्ड भी देता है।" – m0skit0

+0

मैंने अपनी स्पष्टीकरण का विस्तार किया, आशा है कि जब आप डाउनवोट करते हैं तो आप टिप्पणी कर सकते हैं, इसलिए मैं (हम) सीख सकते हैं;) – m0skit0

3

के बाद से सवाल सी (नहीं सी ++) के बारे में है, inline मतलब यह है कि

  1. आप "है कि समारोह के लिए कॉल के रूप में तेजी से संभव के रूप में हो सकता है" (ISO9899-1999, 6.7.4 (5 इच्छा))। वही पैराग्राफ यह भी कहता है कि यह कार्यान्वयन-परिभाषित है कि यह सुझाव किस हद तक प्रभावी है। दूसरे शब्दों में, इसका थोड़ा असर होता है और यह किसी भी इनलाइनिंग को इंगित नहीं करता है (वास्तव में, निर्देश कैश प्रभावों के कारण गैर-इनलाइनिंग संभवतः तेज़ी से हो सकती है)।
  2. वहाँ के साथ extern (ISO9899-1999, 6.7.4 (6), उदाहरण के लिए बाहरी लिंकेज के साथ एक inline funciton एक ही संकलन इकाई में परिभाषित किया जाना चाहिए, और एक इनलाइन परिभाषा की अनुमति देता है कुछ प्रतिबंध और संयोजन में विशेष मामले हैं कहीं एक extern परिभाषा एक त्रुटि के बिना (जो जरूरी एक अच्छी बात नहीं है, क्योंकि दो कार्यों कार्यात्मक रूप से बराबर होने की ज़रूरत नहीं है, और यह अनिर्दिष्ट है जो एक संकलक किसी भी समय का उपयोग करता है!)।

लिंकर निहितार्थ हैप्टीक द्वारा दिए गए सी ++ के लिए आवश्यक हैं, लेकिन सी द्वारा आवश्यक नहीं है (जहां तक ​​मैं कह सकता हूं)। उन्हें आवश्यक रूप से " आईएसओ 14882, 7.1.2 (4) में सभी अनुवाद इकाइयों में एक ही पता होगा " खंड। मुझे सी 99 में किसी भी समान खंड के बारे में पता नहीं है।
हालांकि, चूंकि पूरी तरह से अलग-अलग भाषाएं सी और सी ++ आमतौर पर एक ही सी/सी ++ कंपाइलर और लिंकर से गुज़रती हैं, वैसे भी यह सी के लिए समान रूप से काम करती है, वैसे भी।

तो ... अपने प्रश्न का उत्तर कैसे दें? inline का उपयोग करें जब आपको लगता है कि यह पर्याप्त है। extern के संभावित नुकसान से अवगत रहें। अन्यथा, इसे छोड़ दें और इसे सही करने के लिए कंपाइलर पर भरोसा करें।

+0

यह सुनिश्चित नहीं है कि यह उत्तर कितना वैध है। "जब आप इसे पर्याप्त महसूस करते हैं तो इनलाइन का उपयोग करें" सुझाव देता है कि आप इसका उपयोग नहीं कर सकते हैं, क्या आपको लिंक समय पर कई परिभाषा त्रुटियां नहीं मिलेंगी? –

+0

@ मैट जॉइनर: संभवतः, यह निर्भर करता है।मैं जो कह रहा हूं, वास्तव में कुछ "इनलाइन" बनाने के लिए वास्तव में "सही" या "गलत" नहीं है, जैसा कि कोई अधिकार नहीं है और न ही गलत है कि आप किसी शीर्षलेख या स्रोत में परिभाषा डालते हैं या नहीं - आप इनमें से एक या दोनों कर सकते हैं, और कोई भी आम तौर पर गलत नहीं है, यह एक डिज़ाइन विकल्प है। चाहे आप एक डबल परिभाषा के साथ परेशानी में भाग लें (आप आमतौर पर अपनी चिंता के बारे में सही हैं!) एक अलग मामला है। निश्चित रूप से ओडीआर है। लेकिन शीर्षलेखों को केवल एक बार शामिल किया जा सकता है (हम नहीं जानते), और 'if ifff' है, अगर कुछ और नहीं, तो ... – Damon

+0

... यदि ओपी वास्तव में एक शीर्षलेख में परिभाषा रखना चाहता है , लेकिन यह इसे रेखांकित नहीं करना चाहता (और फिर, कंपाइलर विशेषताएं हैं (यदि पोर्टेबिलिटी कड़ाई से जरूरी नहीं है) जैसे कि 'gnu_inline' जो पूरी तरह से नियमों को फिर से बदलती है।)। यद्यपि उसे शायद #else खंड में एक और बाहरी घोषणा की आवश्यकता होगी ... सुंदर नहीं, लेकिन आह ठीक है ... अंत में, किसी को एक ऐसी चीज़ चुनने की ज़रूरत है जो सही महसूस करे। – Damon

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