2017-12-14 1 views
5

हाल ही में मैं अधिक ओपन सोर्स सी कोड पढ़ने का प्रयास कर रहा हूं। मेरे शौक परियोजनाओं में एक आम पैटर्न जिसे मैं अपना रहा हूं, निम्नानुसार है: -एक हेडर फ़ाइल में स्थिर इनलाइन फ़ंक्शन

मेरी सी फाइलों में, मेरे पास ऐसे कार्य हैं जो स्थिर या निर्यात किए गए हैं। केवल निर्यात किए गए फ़ंक्शंस को हेडर फ़ाइल में रखा जाता है। वैश्विक चर जो केवल किसी ऑब्जेक्ट के दायरे में उपयोग किए जाते हैं, को स्थिर वैश्विक चर के रूप में भी उपयोग किया जाता है।

मेरा प्रश्न हेडर फ़ाइलों के अंदर "स्थैतिक इनलाइन" फ़ंक्शंस रखने की उपयोगिता और प्रेरणा से संबंधित है। जो मैंने ऑनलाइन पढ़ा है, स्थिर कीवर्ड का उपयोग नहीं करने से कई परिभाषा त्रुटि होती है और यही कारण है कि फ़ंक्शन को केवल "इनलाइन" के रूप में परिभाषित करने का कारण नहीं है।

हालांकि, क्या इसका मतलब यह है कि यह फ़ंक्शन अन्य ऑब्जेक्ट्स के उपयोग के लिए निर्यात किया जाता है? यदि हां, तो क्यों नहीं इस फ़ंक्शन को सी फ़ाइल में परिभाषित करें और इसे हेडर फ़ाइल के माध्यम से निर्यात करें? यदि नहीं, तो इसे सीधे फ़ाइल फ़ाइल के अंदर रखने के बजाय हेडर फ़ाइल में क्यों डालें?

क्या इस कोडिंग शैली के पीछे कोई कारण है? मैं क्या खो रहा हूँ?

ऐसा ही एक उदाहरण hashmap.h अंदर Git codebase में पाया जा सकता:

/* 
* Converts a cryptographic hash (e.g. SHA-1) into an int-sized hash code 
* for use in hash tables. Cryptographic hashes are supposed to have 
* uniform distribution, so in contrast to `memhash()`, this just copies 
* the first `sizeof(int)` bytes without shuffling any bits. Note that 
* the results will be different on big-endian and little-endian 
* platforms, so they should not be stored or transferred over the net. 
*/ 
static inline unsigned int sha1hash(const unsigned char *sha1) 
{ 
    /* 
    * Equivalent to 'return *(unsigned int *)sha1;', but safe on 
    * platforms that don't support unaligned reads. 
    */ 
    unsigned int hash; 
    memcpy(&hash, sha1, sizeof(hash)); 
    return hash; 
} 
+4

एक भी संक्षिप्त प्रश्न उदाहरण के साथ समर्थित पोस्ट करें, नहीं एक है कि वरीय के विस्तार जरूरत पर जोर देता " कोडिंग शैलियों "। – Fabulous

+0

आपके संदर्भ के लिए: https://stackoverflow.com/help/mcve – Fabulous

+1

"निर्यात" करके आपका मतलब "बाहरी" है? क्या आप शायद अधिक विशेष रूप से "बाहरी 'स्टोरेज-क्लास विनिर्देशक के साथ घोषित किया गया है? –

उत्तर

5

एक static inline समारोह है, व्यवहार में, संभावना (लेकिन कुछ नहीं) inlined कुछ अच्छा अनुकूलन संकलक द्वारा होने के लिए (जैसे GCC द्वारा जब इसे -O2 दिया जाता है) इसकी अधिकांश कॉल साइटों पर।

इसे हेडर फ़ाइल में परिभाषित किया गया है, क्योंकि इसे तब अधिकांश कॉल साइटों (शायद उन सभी में) पर रेखांकित किया जा सकता है। यदि यह महज था घोषित (और बस "निर्यात") इनलाइनिंग होने की संभावना नहीं (सिवाय अगर आप और लिंक संकलन link-time optimizations, उर्फ ​​LTO साथ, यह भी, जैसे संकलन और gcc -flto -O2 साथ लिंक, और कहा कि एक बहुत बढ़ जाती है बिल्ड समय)।

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

कंपाइलर ने इनलाइन नहीं किया है (उदाहरण के लिए जब आप इसका पता उपयोग करते हैं) में एकाधिक परिभाषाओं (लिंक समय पर) से बचने के लिए static घोषित किया जाता है।

प्रैक्टिस में, सी 99 या सी 11 कोड (एलटीओ को छोड़कर, जिसे मैं शायद ही कभी उपयोग करता हूं) में, मैं हमेशा छोटे कार्यों को रखता हूं जिन्हें मैं static inline सामान्य हेडर फ़ाइलों में परिभाषाओं के रूप में रेखांकित करना चाहता हूं।

यह समझना सुनिश्चित करें कि C preprocessor कैसे काम करता है। ध्यान दें कि आप सैद्धांतिक रूप से (लेकिन यह बहुत खराब अभ्यास और घृणास्पद शैली होगी) एक सामान्य शीर्षलेख फ़ाइल में कुछ static inline फ़ंक्शन को परिभाषित करने से बचें और इसके बजाय कई .c फ़ाइलों में अपनी समान परिभाषा को कॉपी और पेस्ट करें। (हालांकि, .c फ़ाइलों के लिए उत्पन्न हो सकता है, उदाहरण के लिए, यदि आप compiler emitting C code डिज़ाइन करते हैं)।using the lto1 frontend - -

FYI करें LTO व्यावहारिक रूप से कुछ आंतरिक संकलक प्रतिनिधित्व (कुछ GIMPLE) वस्तु फ़ाइलों के अंदर एम्बेड करने, और कुछ "संकलन" कदम redoing द्वारा हाल ही में जीसीसी compilers द्वारा कार्यान्वित किया जाता "लिंक" समय में। अभ्यास में, पूरा कार्यक्रम लगभग "दो बार" संकलित किया जाता है।

(वास्तव में, मैं हमेशा सोचा है कि सी मानकीकरण समिति के बजाय तय नहीं किया है कि सभी स्पष्ट रूप से inline कार्यों स्थिर कर रहे हैं)

+1

शायद सी ++ की 'इनलाइन' wrt 'static' चीज़' के साथ अंतर का उल्लेख करने लायक है (spoiler: मैं विवरण के बारे में भूल जाता रहता हूं, इसलिए मैं कोई भी अच्छा सारांश देने के लिए बहुत आभारी हूं)। –

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