निम्नलिखित देखें:

https://en.cppreference.com/w/cpp/language/definition#One_Definition_Rule

http://eel.is/c++draft/basic.def.odr#12

इसमें कहा गया है कि क्लास टेम्प्लेट की कई परिभाषाएं, क्लास टेम्प्लेट के स्थिर डेटा सदस्य, आंशिक टेम्प्लेट विशेषज्ञता आदि की अनुमति है और यह एक ही परिभाषा के रूप में कार्य करेगा। बढ़िया... लेकिन यह कहीं भी परिवर्तनीय टेम्पलेट्स का उल्लेख नहीं करता है?

यदि मेरे पास एकाधिक अनुवाद इकाइयों में निम्नलिखित हैं:

template<typename T>
T my_data{};

inline void test() {
    my_data<int> = 1;
}

क्या प्रत्येक अनुवाद इकाई को my_data की अपनी परिभाषा दी जाएगी जिसके परिणामस्वरूप कई प्रतीक होंगे, या क्या वे सभी प्रभावी रूप से कार्यक्रम के भीतर एक ही परिभाषा में विलय हो जाएंगे जहां एक अनुवाद इकाई में test() को कॉल करने से वेरिएबल बदल जाएगा। दूसरी अनुवाद इकाई के लिए?

मानक में यह इस व्यवहार का उल्लेख कहां करता है?

5
Tin Tin 3 अक्टूबर 2018, 18:00

1 उत्तर

सबसे बढ़िया उत्तर

C++14 मानक के अनुसार [basic.def]/ 4:

प्रत्येक प्रोग्राम में प्रत्येक गैर-इनलाइन फ़ंक्शन या वेरिएबल की ठीक एक परिभाषा होनी चाहिए जिसका उपयोग उस प्रोग्राम में एक खारिज किए गए कथन के बाहर किया जाता है; कोई निदान की आवश्यकता नहीं है।

इसलिए यदि my_data<T> को एकाधिक अनुवाद इकाई में समान टेम्पलेट तर्क के साथ ऑर्ड-यूज़ किया जाता है, तो आपके पास एक ओडीआर-उल्लंघन होना चाहिए (बिना किसी निदान के)। inline चर उस समस्या को हल करने के लिए c++17 में दिखाई दिए और यही कारण है कि type_traits *_v चर टेम्पलेट के परिवार को inline घोषित किया गया है।

व्यवहार में, जीसीसी और क्लैंग (कम से कम, मैं अन्य कंपाइलरों की जांच नहीं कर सकता) के साथ, आपको कोई ओडीआर उल्लंघन नहीं मिलेगा क्योंकि टेम्पलेट चर में "अस्पष्ट संबंध" है (जैसे कि उन्हें इनलाइन घोषित किया गया था)।

आप इसे nm से जांच सकते हैं। यदि आप यह कमांड लाइन g++ -c test.cpp -std=c++14 && nm test.o | c++filt | grep my_data चलाते हैं, तो आपको यह देखना चाहिए कि my_data<int> एक श्रेणी का प्रतीक है u जो कि nm दस्तावेज के अनुसार है:

प्रतीक एक अद्वितीय वैश्विक प्रतीक है। यह ELF प्रतीक बाइंडिंग के मानक सेट का GNU एक्सटेंशन है। इस तरह के प्रतीक के लिए गतिशील लिंकर यह सुनिश्चित करेगा कि पूरी प्रक्रिया में इस नाम और प्रकार के उपयोग में केवल एक प्रतीक है।


मुख्य अंक #1849 में कोई भी इस अस्पष्ट को पढ़ सकता है वाक्य:

६.२ [basic.def.odr] पैराग्राफ ६ में जब संस्थाओं को एक कार्यक्रम में गुणा-घोषित किया जा सकता है, तो इसका विवरण चर टेम्पलेट्स पर चर्चा नहीं करना चाहिए।

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

2
Oliv 3 अक्टूबर 2018, 20:14