मुझे लगता है कि आप यहाँ कुछ याद कर रहे हैं।
स्थिर कार्य?
किसी फ़ंक्शन को स्थिर घोषित करने से वह अपनी संकलन इकाई में "छिपा हुआ" हो जाएगा।
नाम स्थान स्कोप (3.3.6) में आंतरिक लिंकेज है यदि यह नाम है
- एक चर, फ़ंक्शन या फ़ंक्शन टेम्पलेट जिसे स्पष्ट रूप से स्थिर घोषित किया गया है;
3.5 / 3 - सी ++ 14 (n3797)
जब किसी नाम में आंतरिक जुड़ाव होता है, तो उसे निरूपित करने वाली इकाई को उसी अनुवाद इकाई में अन्य स्कोप के नामों से संदर्भित किया जा सकता है।
3.5 / 2 - सी ++ 14 (n3797)
यदि आप हेडर में इस स्थिर फ़ंक्शन को घोषित करते हैं, तो इस हेडर सहित सभी संकलन इकाइयों की फ़ंक्शन की अपनी प्रतिलिपि होगी।
बात यह है कि यदि उस फ़ंक्शन के अंदर स्थिर चर हैं, तो इस हेडर सहित प्रत्येक संकलन इकाई का अपना निजी संस्करण भी होगा।
इनलाइन फ़ंक्शन?
इनलाइन की घोषणा करना इसे इनलाइनिंग के लिए एक उम्मीदवार बनाता है (इसका आजकल सी ++ में बहुत अधिक मतलब नहीं है, क्योंकि कंपाइलर इनलाइन होगा या नहीं, कभी-कभी इस तथ्य को अनदेखा करना कि कीवर्ड इनलाइन मौजूद है या अनुपस्थित है):
इनलाइन विनिर्देशक के साथ एक फ़ंक्शन घोषणा (8.3.5, 9.3, 11.3) एक इनलाइन फ़ंक्शन घोषित करता है। इनलाइन स्पेसियर कार्यान्वयन को इंगित करता है कि कॉल के बिंदु पर फ़ंक्शन बॉडी के इनलाइन प्रतिस्थापन को सामान्य फ़ंक्शन सिस्टम तंत्र के लिए प्राथमिकता दी जानी है। कॉल के बिंदु पर इस इनलाइन प्रतिस्थापन को निष्पादित करने के लिए एक कार्यान्वयन की आवश्यकता नहीं है; हालाँकि, भले ही इस इनलाइन प्रतिस्थापन को छोड़ दिया गया हो, 7.1.2 द्वारा परिभाषित इनलाइन फ़ंक्शन के लिए अन्य नियमों का अभी भी सम्मान किया जाएगा।
7.1.2 / 2 - C ++ 14 (n3797)
एक हेडर में, इसका एक दिलचस्प दुष्प्रभाव होता है: इनलाइन फ़ंक्शन को एक ही मॉड्यूल में कई बार परिभाषित किया जा सकता है, और लिंकर केवल एक में "उन्हें" जोड़ देगा (यदि वे संकलक के कारण के लिए इनबिल्ड नहीं थे)।
अंदर घोषित किए गए स्थिर चरों के लिए, मानक विशेष रूप से एक कहता है, और उनमें से केवल एक:
एक बाहरी इनलाइन फ़ंक्शन में एक स्थिर स्थानीय चर हमेशा एक ही ऑब्जेक्ट को संदर्भित करता है।
7.1.2 / 4 - C ++ 98 / C ++ 14 (n3797)
(फ़ंक्शन डिफ़ॉल्ट बाहरी रूप से होते हैं, इसलिए, जब तक आप विशेष रूप से अपने फ़ंक्शन को स्थिर के रूप में चिह्नित नहीं करते हैं, यह उस फ़ंक्शन पर लागू होता है)
इसका लाभ "स्थिर" है (अर्थात इसे हेडर में परिभाषित किया जा सकता है) इसकी खामियों के बिना (यह सबसे अधिक बार मौजूद है यदि यह इनलेट नहीं है)
स्थिर स्थानीय चर?
स्टेटिक लोकल वेरिएबल्स का कोई लिंकेज नहीं है (उन्हें उनके दायरे से बाहर के नाम से संदर्भित नहीं किया जा सकता है), लेकिन स्टैटिक स्टोरेज की अवधि है (यानी यह वैश्विक है, लेकिन इसका निर्माण और विनाश विशिष्ट नियमों का पालन करता है)।
स्थिर + इनलाइन?
इनलाइन और स्टैटिक को मिलाने पर आपके द्वारा वर्णित परिणाम (भले ही फ़ंक्शन के इनलाइन होने पर भी, स्थिर वैरिएबल अंदर न हों, और आपके स्थैतिक फ़ंक्शंस की परिभाषा सहित संकलन इकाइयाँ उतनी ही अधिक स्थिर होती हैं) )।
लेखक के अतिरिक्त प्रश्न का उत्तर
चूँकि मैंने प्रश्न लिखा था जिसे मैंने विजुअल स्टूडियो 2008 के साथ आज़माया था। मैंने उन सभी विकल्पों को चालू करने की कोशिश की, जो मानकों के अनुपालन में वीएस अधिनियम बनाते हैं, लेकिन यह संभव है कि मैं कुछ चूक गया। ये परिणाम हैं:
जब फ़ंक्शन केवल "इनलाइन" होता है, तो स्थैतिक चर की केवल एक प्रति होती है।
जब फ़ंक्शन "स्थिर इनलाइन" होता है, तो अनुवाद इकाइयों के रूप में कई प्रतियां होती हैं।
असली सवाल अब यह है कि क्या चीजों को इस तरह से माना जाता है, या यदि यह Microsoft C ++ कंपाइलर का एक idiosyncrasy है।
तो मुझे लगता है कि आपके पास ऐसा कुछ है:
void doSomething()
{
static int value ;
}
आपको यह महसूस होना चाहिए कि फ़ंक्शन के अंदर का स्टैटिक वैरिएबल, साधारण शब्दों में, एक वैरिएबल वैरिएबल जिसे सभी के लिए छिपाया गया है, लेकिन फंक्शन का स्कोप, जिसका अर्थ है कि केवल फंक्शन को ही अंदर घोषित किया गया है।
फ़ंक्शन को सम्मिलित करने से कुछ भी नहीं बदलेगा:
inline void doSomething()
{
static int value ;
}
केवल एक छिपा हुआ वैश्विक चर होगा। संकलक तथ्य को इनलाइन करने की कोशिश करेगा कोड इस तथ्य को नहीं बदलेगा कि केवल एक वैश्विक छिपा हुआ चर है।
अब, यदि आपका कार्य स्थिर घोषित किया गया है:
static void doSomething()
{
static int value ;
}
फिर यह प्रत्येक संकलन इकाई के लिए "निजी" है, जिसका अर्थ है कि प्रत्येक सीपीपी फ़ाइल जिसमें हेडर शामिल है जहां स्थिर फ़ंक्शन घोषित किया गया है, समारोह की अपनी निजी प्रतिलिपि होगी, जिसमें वैश्विक छिपी चर की अपनी निजी प्रतिलिपि भी शामिल है, इस प्रकार जितनी अधिक चर हेडर सहित संकलन इकाइयाँ हैं।
"स्थिर" चर के साथ "इनलाइन" को "स्थिर" चर के साथ जोड़ना:
inline static void doSomething()
{
static int value ;
}
इस "इनलाइन" कीवर्ड को नहीं जोड़ने का एक ही परिणाम है, जहां तक स्थिर वैरिएबल का संबंध है।
तो VC ++ का व्यवहार सही है, और आप "इनलाइन" और "स्थिर" के वास्तविक अर्थ को गलत कर रहे हैं।