क्या C ++ 17, C ++ 14, और C ++ 11 ऑब्जेक्ट लिंक करना सुरक्षित है


101

मान लीजिए कि मेरे पास तीन संकलित वस्तुएं हैं, जो सभी एक ही संकलक / संस्करण द्वारा निर्मित हैं :

  1. A को C ++ 11 मानक के साथ संकलित किया गया था
  2. B को C ++ 14 मानक के साथ संकलित किया गया था
  3. C को C ++ 17 मानक के साथ संकलित किया गया था

सादगी के लिए, मान लें कि सभी हेडर C ++ 11 में लिखे गए थे, केवल उन निर्माणों का उपयोग करते हुए जिनके शब्दार्थ सभी तीन मानक संस्करणों के बीच नहीं बदले हैं , और इसलिए किसी भी अन्योन्याश्रितियों को हेडर समावेशन के साथ सही ढंग से व्यक्त किया गया था और संकलक ने कोई आपत्ति नहीं की थी।

इन वस्तुओं का कौन सा संयोजन है और क्या यह एक एकल बाइनरी में लिंक करना सुरक्षित नहीं है? क्यों?


संपादित करें: प्रमुख संकलक (जैसे gcc, clang, बनाम ++) को कवर करने वाले उत्तर स्वागत योग्य हैं


6
विद्यालय / साक्षात्कार प्रश्न नहीं। प्रश्न एक विशेष मामले से उपजा है: मैं एक प्रोजेक्ट पर काम कर रहा हूं जो एक ओपन-सोर्स लाइब्रेरी पर निर्भर करता है। मैं स्रोत से इस पुस्तकालय का निर्माण करता हूं, लेकिन इसकी निर्माण प्रणाली केवल C ++ 03 / C ++ 11 भवन के बीच चयन करने के लिए एक ध्वज को स्वीकार करती है। संकलक का उपयोग मैं अन्य मानकों का समर्थन करता हूं, और मैं अपने स्वयं के प्रोजेक्ट को C ++ 17 में अपग्रेड करने पर विचार कर रहा हूं। मैं अनिश्चित हूं कि क्या यह एक सुरक्षित निर्णय है। क्या एबीआई या किसी अन्य तरीके से विराम हो सकता है जिसमें दृष्टिकोण उचित नहीं है? मुझे स्पष्ट उत्तर नहीं मिला और सामान्य मामले के बारे में एक प्रश्न पोस्ट करने का फैसला किया।
रिकाब

6
यह पूरी तरह से कंपाइलर पर निर्भर करता है। औपचारिक C ++ विनिर्देशों में कुछ भी नहीं है जो इस स्थिति को नियंत्रित करता है। एक छोटी संभावना यह भी है कि कोड जो C ++ 03 या C + 11 मानकों को लिखा गया था, उसमें C ++ 14 और C ++ 17 स्तर पर कुछ मुद्दे होंगे। पर्याप्त ज्ञान और अनुभव (और अच्छी तरह से लिखित कोड के साथ शुरू करने के लिए), इनमें से किसी भी मुद्दे को ठीक करना संभव होना चाहिए। यदि आप, हालांकि, नए C ++ मानकों से बहुत परिचित नहीं हैं, तो आप बिल्ड सिस्टम का समर्थन करने से चिपके रहते हैं, और साथ काम करने के लिए परीक्षण किया जाता है।
सैम वर्शविक १ '

10
@Someprogrammerdude: यह एक अत्यंत सार्थक प्रश्न है। काश मेरे पास जवाब होता। मुझे पता है कि आरएचईएल डेवलेसेट के माध्यम से libstdc ++ डिज़ाइन द्वारा पिछड़े संगत है, नए सामान में स्टेटिकली लिंकिंग करके और पुराने सामान को डिस्ट्रो के "नेटिव" libstdit ++ का उपयोग करके रनटाइम पर हल करने के लिए पुराना है। लेकिन इस सवाल का जवाब नहीं है।
ऑर्बिट

4
@nm: ... जो कि ज्यादातर मामला है ... बहुत अधिक जो वितरण-स्वतंत्र C ++ पुस्तकालयों को वितरित करता है, वह (1) गतिशील पुस्तकालय रूप में और (2) बिना C ++ मानक पुस्तकालय कंटेनरों के इंटरफ़ेस सीमाओं पर ऐसा करता है। लिनक्स वितरण से आने वाले पुस्तकालय आसान होते हैं क्योंकि वे सभी एक ही संकलक, समान मानक पुस्तकालय और झंडे के बहुत समान डिफ़ॉल्ट सेट के साथ निर्मित होते हैं।
मट्टियो इटालिया

3
बस @MatteoItalia से पहले की टिप्पणी को स्पष्ट करने के लिए "और C ++ 03 से C ++ 11 मोड पर स्विच करना (विशेष रूप से std :: string)।" यह सच नहीं है, std::stringlibstdc ++ में सक्रिय कार्यान्वयन उपयोग किए गए -stdमोड से स्वतंत्र है । यह एक महत्वपूर्ण संपत्ति है, ठीक ओपी की तरह समर्थन स्थितियों के लिए। आप std::stringC ++ 03 कोड में नए का उपयोग कर सकते हैं , और आप std::stringC ++ 11 कोड में पुराने का उपयोग कर सकते हैं (Matteo के बाद की टिप्पणी में लिंक देखें)।
जोनाथन वेकली

जवाबों:


121

इन वस्तुओं का कौन सा संयोजन है और क्या यह एक एकल बाइनरी में लिंक करना सुरक्षित नहीं है? क्यों?

GCC के लिए ऑब्जेक्ट A, B, और C. के किसी भी संयोजन को एक साथ जोड़ना सुरक्षित है। यदि वे सभी एक ही संस्करण के साथ बनाए गए हैं, तो वे ABI संगत हैं, मानक संस्करण (अर्थात -stdविकल्प) से कोई फर्क नहीं पड़ता है।

क्यों? क्योंकि यह हमारे कार्यान्वयन की एक महत्वपूर्ण संपत्ति है जिसे सुनिश्चित करने के लिए हम कड़ी मेहनत करते हैं।

जहां आपको समस्याएं हैं यदि आप एक साथ लिंक करते हैं तो GCC के विभिन्न संस्करणों के साथ संकलित वस्तुएं और जीसीसी के उस मानक के लिए समर्थन पूरा होने से पहले आपने नए C ++ मानक से अस्थिर सुविधाओं का उपयोग किया है। उदाहरण के लिए, यदि आप GCC 4.9 और -std=c++11GCC 5 के साथ एक वस्तु का उपयोग करते हैं और -std=c++11आपको समस्याएं होंगी। C ++ 11 समर्थन GCC 4.x में प्रयोगात्मक था, और इसलिए GCC 4.9 और C ++ 11 सुविधाओं के 5 संस्करणों के बीच असंगत परिवर्तन हुए थे। इसी प्रकार, यदि आप GCC 7 के साथ एक वस्तु और -std=c++17GCC 8 के साथ कोई अन्य वस्तु संकलित करते हैं और -std=c++17आपको समस्याएं होंगी, क्योंकि GCC 7 और 8 में C ++ 17 समर्थन अभी भी प्रायोगिक और विकसित हो रहा है।

दूसरी ओर, निम्नलिखित वस्तुओं का कोई भी संयोजन काम करेगा (हालाँकि libstdc++.soसंस्करण के बारे में नीचे देखें ):

  • ऑब्जेक्ट डी को जीसीसी 4.9 और के साथ संकलित किया गया -std=c++03
  • ऑब्जेक्ट E को GCC 5 और के साथ संकलित किया गया है -std=c++11
  • ऑब्जेक्ट F को GCC 7 और के साथ संकलित किया गया -std=c++17

ऐसा इसलिए है क्योंकि प्रयुक्त सभी तीन संकलक संस्करणों में C ++ 03 समर्थन स्थिर है, और इसलिए C ++ 03 घटक सभी वस्तुओं के बीच संगत हैं। GCC 5 के बाद से C ++ 11 समर्थन स्थिर है, लेकिन ऑब्जेक्ट D किसी C ++ 11 सुविधाओं का उपयोग नहीं करता है, और ऑब्जेक्ट E और F दोनों उन संस्करणों का उपयोग करते हैं जहां C ++ 11 समर्थन स्थिर है। C ++ 17 समर्थन किसी भी संकलित संकलक संस्करणों में स्थिर नहीं है, लेकिन केवल ऑब्जेक्ट F C ++ 17 सुविधाओं का उपयोग करता है और इसलिए अन्य दो ऑब्जेक्ट्स के साथ कोई संगतता समस्या नहीं है (केवल वे सुविधाएँ जो C ++ 03 से आती हैं। या C ++ 11, और उपयोग किए गए संस्करण उन भागों को ठीक बनाते हैं)। यदि आप बाद में एक चौथी वस्तु को संकलित करना चाहते हैं, जी, जीसीसी 8 का उपयोग करके और -std=c++17फिर आपको उसी संस्करण के साथ एफ को फिर से जोड़ना होगा (या एफ से लिंक नहीं करना चाहिए) क्योंकि एफ और जी में C ++ 17 प्रतीक असंगत हैं।

डी, ई और एफ के बीच ऊपर वर्णित संगतता के लिए एकमात्र चेतावनी यह है कि आपके कार्यक्रम को libstdc++.soजीसीसी 7 (या बाद में) से साझा पुस्तकालय का उपयोग करना चाहिए । क्योंकि ऑब्जेक्ट F को GCC 7 के साथ संकलित किया गया था, इसलिए आपको उस रिलीज़ से साझा लाइब्रेरी का उपयोग करने की आवश्यकता है, क्योंकि GCC 7 के साथ कार्यक्रम के किसी भी हिस्से को संकलित करना उन प्रतीकों पर निर्भरता का परिचय दे सकता है जो libstdc++.soGCC 4.9 या GCC 5 से मौजूद नहीं हैं । इसी तरह, यदि आप GCC 8 के साथ निर्मित ऑब्जेक्ट G से जुड़े हैं, तो आपको GCC 8 से उपयोग करने की आवश्यकता होगी libstdc++.soताकि यह सुनिश्चित हो सके कि G द्वारा आवश्यक सभी चिन्ह मिल गए हैं। साझा पुस्तकालय को सुनिश्चित करने के लिए सरल नियम यह है कि रन-टाइम पर प्रोग्राम का उपयोग कम से कम उतना ही नया है जितना कि किसी भी ऑब्जेक्ट को संकलित करने के लिए उपयोग किया जाने वाला संस्करण।

जीसीसी का उपयोग करते समय एक और चेतावनी, आपके प्रश्न पर टिप्पणियों में पहले से ही उल्लेख किया गया है, कि जीसीसी 5 के बाद से libstdc ++ में दो कार्यान्वयनstd::string उपलब्ध हैं। दो कार्यान्वयन लिंक-संगत नहीं हैं (उनके अलग-अलग नाम हैं, इसलिए उन्हें एक साथ जोड़ा नहीं जा सकता) लेकिन एक ही बाइनरी में सह-अस्तित्व हो सकता है (उनके अलग-अलग नाम हैं, इसलिए यदि कोई वस्तु का उपयोग करता है std::stringऔर संघर्ष न करें तो) अन्य उपयोग std::__cxx11::string)। यदि आपकी वस्तुएं उपयोग करती हैं, std::stringतो आमतौर पर वे सभी समान स्ट्रिंग कार्यान्वयन के साथ संकलित किए जाने चाहिए। -D_GLIBCXX_USE_CXX11_ABI=0मूल gcc4-compatibleकार्यान्वयन -D_GLIBCXX_USE_CXX11_ABI=1का चयन करने के लिए , या नए cxx11कार्यान्वयन का चयन करने के लिए संकलन करें (नाम से मूर्ख न बनें, इसका उपयोग C ++ 03 में भी किया जा सकता है, इसे कहा जाता हैcxx11क्योंकि यह C ++ 11 आवश्यकताओं के अनुरूप है)। कौन सा कार्यान्वयन डिफ़ॉल्ट है यह निर्भर करता है कि जीसीसी को कैसे कॉन्फ़िगर किया गया था, लेकिन डिफ़ॉल्ट हमेशा मैक्रो के साथ संकलन-समय पर ओवरराइड किया जा सकता है।


"क्योंकि GCC 7 के साथ कार्यक्रम के किसी भी भाग को संकलित करना प्रतीकों पर निर्भरता का परिचय दे सकता है जो libstdc ++ में मौजूद है। इसलिए GCC 4.9 या GCC 5 से" आपका मतलब है कि GCC 4.9 या GCC 5 से मौजूद नहीं हैं, सही? क्या यह स्थैतिक लिंकिंग पर भी लागू होता है? संकलक संस्करणों में संगतता पर जानकारी के लिए धन्यवाद।
हाडी ब्रिस

1
मैंने अभी इस प्रश्न पर एक भरपूर पेशकश करने में भारी खामी का एहसास किया है। 😂
ऑर्बिट

4
@ricab मैं 90% यकीन है कि जवाब क्लैंग / libc ++ के लिए समान है, लेकिन मुझे MSVC के बारे में कोई पता नहीं है।
जोनाथन वॉकली

1
यह उत्तर तारकीय है। क्या यह कहीं दस्तावेज है कि 5.0+ 11/14 के लिए स्थिर है?
बैरी

1
बहुत स्पष्ट रूप से या एक जगह पर नहीं। gcc.gnu.org/gcc-5/changes.html#libstdcxx और gcc.gnu.org/onbuildocs/libstdc++/manual/api.html#api.rel_51 , C ++ 11 के लिए पुस्तकालय समर्थन की घोषणा पूर्ण होने के लिए (भाषा) समर्थन सुविधा-पूर्ण पहले था, लेकिन अभी भी "प्रयोगात्मक")। C ++ 14 लाइब्रेरी समर्थन अभी भी 6.1 तक प्रयोगात्मक के रूप में सूचीबद्ध है, लेकिन मुझे लगता है कि अभ्यास में 5.x और 6.x के बीच कुछ भी नहीं बदला जो ABI को प्रभावित करता है।
जोनाथन वेकली

17

उत्तर के दो भाग हैं। कंपाइलर स्तर पर संगतता और लिंकर स्तर पर संगतता। पूर्व से शुरू करते हैं।

मान लीजिए कि सभी हेडर C ++ 11 में लिखे गए थे

समान संकलक का उपयोग करने का अर्थ है कि समान मानक लाइब्रेरी हेडर और स्रोत फाइलें (कंपाइलर से जुड़े प्याज) का उपयोग लक्ष्य C ++ मानक के बावजूद किया जाएगा। इसलिए, मानक लाइब्रेरी की हेडर फाइलें संकलक द्वारा समर्थित सभी C ++ संस्करणों के साथ संगत होने के लिए लिखी जाती हैं।

कहा कि, यदि अनुवाद इकाई के संकलन के लिए प्रयुक्त संकलक विकल्प किसी विशेष C ++ मानक को निर्दिष्ट करते हैं, तो जो भी सुविधाएँ केवल नए मानकों में उपलब्ध हैं, वे सुलभ नहीं होनी चाहिए। यह __cplusplusनिर्देश का उपयोग करके किया जाता है । यह कैसे उपयोग किया जाता है के एक दिलचस्प उदाहरण के लिए वेक्टर स्रोत फ़ाइल देखें । इसी तरह, संकलक मानक के नए संस्करणों द्वारा प्रस्तुत किसी भी वाक्यविन्यास सुविधाओं को अस्वीकार कर देगा।

उस सभी का मतलब है कि आपकी धारणा केवल आपके द्वारा लिखी गई हेडर फाइलों पर लागू हो सकती है। ये हेडर फाइलें विभिन्न C ++ मानकों को लक्षित करने वाली विभिन्न अनुवाद इकाइयों में शामिल होने पर असंगति पैदा कर सकती हैं। यह C ++ मानक के अनुलग्नक सी में चर्चा की गई है। 4 खंड हैं, मैं केवल पहले एक पर चर्चा करूंगा, और बाकी का संक्षेप में उल्लेख करूंगा।

C.3.1 क्लॉज 2: लेक्सिकल कन्वेंशन

एकल उद्धरण C ++ 11 में एक वर्ण शाब्दिक परिसीमन करते हैं, जबकि वे C ++ 14 और C ++ 17 में अंक विभाजक हैं। मान लें कि आपके पास शुद्ध C ++ 11 हेडर फ़ाइलों में से एक में स्थूल परिभाषा है:

#define M(x, ...) __VA_ARGS__

// Maybe defined as a field in a template or a type.
int x[2] = { M(1'2,3'4) };

दो अनुवाद इकाइयों पर विचार करें जिनमें हेडर फ़ाइल शामिल है, लेकिन क्रमशः C ++ 11 और C ++ 14 को लक्षित करें। C ++ 11 को लक्षित करते समय, उद्धरणों के भीतर अल्पविराम को पैरामीटर विभाजक नहीं माना जाता है; केवल एक बार पैरामीटर है। इसलिए, कोड इसके बराबर होगा:

int x[2] = { 0 }; // C++11

दूसरी ओर, C ++ 14 को लक्षित करते समय, एकल उद्धरणों को अंक विभाजकों के रूप में व्याख्या की जाती है। इसलिए, कोड इसके बराबर होगा:

int x[2] = { 34, 0 }; // C++14 and C++17

यहाँ मुद्दा यह है कि शुद्ध C ++ 11 हेडर फ़ाइलों में से एक में एकल उद्धरणों का उपयोग करने से अनुवाद इकाइयों में आश्चर्यजनक बग हो सकते हैं जो C ++ 14/17 को लक्षित करते हैं। इसलिए, भले ही हेडर फ़ाइल C ++ 11 में लिखी गई हो, यह सुनिश्चित करने के लिए सावधानीपूर्वक लिखा जाना चाहिए कि यह मानक के बाद के संस्करणों के साथ संगत है। __cplusplusनिर्देश यहाँ उपयोगी हो सकता है।

मानक से अन्य तीन खंडों में शामिल हैं:

C.3.2 खण्ड 3: मूल अवधारणाएं

परिवर्तन : नया सामान्य (गैर-प्लेसमेंट) डीलर

तर्क : आकार के निपटारे के लिए आवश्यक है।

मूल सुविधा पर प्रभाव : मान्य C ++ 2011 कोड एक वैश्विक प्लेसमेंट आवंटन फ़ंक्शन और डीलक्लोलेशन फ़ंक्शन की घोषणा कर सकता है:

void operator new(std::size_t, std::size_t); 
void operator delete(void*, std::size_t) noexcept;

इस अंतर्राष्ट्रीय मानक में, हालांकि, ऑपरेटर हटाने की घोषणा एक पूर्वनिर्धारित सामान्य (गैर-प्लेसमेंट) ऑपरेटर हटाने (3.7.4) से मेल खा सकती है। यदि ऐसा है, तो कार्यक्रम बीमार है, क्योंकि यह वर्ग के सदस्य आवंटन कार्यों और डीलरशिप कार्यों (5.3.4) के लिए था।

C.3.3 क्लॉज 7: घोषणाएं

परिवर्तन : कॉन्स्टैक्स गैर-स्थैतिक सदस्य फ़ंक्शंस अव्यवस्थित रूप से कॉन्स्टेबल सदस्य फ़ंक्शंस नहीं हैं।

Rationale : ऑब्जेक्ट को म्यूट करने के लिए constexpr सदस्य फ़ंक्शन को अनुमति देने के लिए आवश्यक है।

मूल सुविधा पर प्रभाव : मान्य C ++ 2011 कोड इस अंतर्राष्ट्रीय मानक में संकलित करने में विफल हो सकता है।

उदाहरण के लिए, निम्नलिखित कोड C ++ 2011 में मान्य है लेकिन इस अंतर्राष्ट्रीय मानक में अमान्य है क्योंकि यह एक ही सदस्य फ़ंक्शन को दो बार अलग-अलग रिटर्न के साथ घोषित करता है:

struct S {
constexpr const int &f();
int &f();
};

C.3.4 क्लाज 27: इनपुट / आउटपुट लाइब्रेरी

बदलें : परिभाषित नहीं किया गया है।

औचित्य : प्राप्त का उपयोग खतरनाक माना जाता है।

मूल सुविधा पर प्रभाव : वेलिड C ++ 2011 कोड जो कि फ़ंक्शन का उपयोग करता है, इस अंतर्राष्ट्रीय मानक में संकलित करने में विफल हो सकता है।

C.4 14 और C ++ 17 के बीच संभावित असंगतताओं पर C.4 में चर्चा की गई है। चूंकि सभी गैर-मानक हेडर फाइलें C ++ 11 (जैसा कि प्रश्न में निर्दिष्ट है) में लिखी गई हैं, ये मुद्दे नहीं होंगे, इसलिए मैं यहां उनका उल्लेख नहीं करूंगा।

अब मैं लिंकर स्तर पर संगतता पर चर्चा करूंगा। सामान्य तौर पर, असंगतियों के संभावित कारणों में निम्नलिखित शामिल हैं:

यदि परिणामी ऑब्जेक्ट फ़ाइल का प्रारूप लक्ष्य C ++ मानक पर निर्भर करता है, तो लिंकर को विभिन्न ऑब्जेक्ट फ़ाइलों को लिंक करने में सक्षम होना चाहिए। जीसीसी, एलएलवीएम और वीसी ++ में, यह सौभाग्य से मामला नहीं है। यही है, ऑब्जेक्ट फ़ाइलों का प्रारूप लक्ष्य मानक के समान है, हालांकि यह संकलक पर अत्यधिक निर्भर है। वास्तव में, जीसीसी, एलएलवीएम और वीसी ++ के लिंकर्स में से किसी को भी लक्ष्य सी ++ मानक के बारे में ज्ञान की आवश्यकता नहीं है। इसका मतलब यह भी है कि हम ऑब्जेक्ट फ़ाइलों को पहले से संकलित कर सकते हैं (स्टेटिक रूप से रनटाइम को लिंक कर रहे हैं)।

यदि प्रोग्राम स्टार्टअप रुटीन (फ़ंक्शन जो कॉल करता है main) विभिन्न C ++ मानकों के लिए अलग है और विभिन्न रूटीन एक दूसरे के साथ संगत नहीं हैं, तो ऑब्जेक्ट फ़ाइलों को लिंक करना संभव नहीं होगा। जीसीसी, एलएलवीएम और वीसी ++ में, यह सौभाग्य से मामला नहीं है। इसके अलावा, mainफ़ंक्शन के हस्ताक्षर (और उस पर लागू प्रतिबंध, मानक की धारा 3.6 देखें) सभी C ++ मानकों में समान है, इसलिए यह कोई फर्क नहीं पड़ता कि यह अनुवाद इकाई किसमें मौजूद है।

सामान्य तौर पर, WPO विभिन्न C ++ मानकों का उपयोग करके संकलित ऑब्जेक्ट फ़ाइलों के साथ अच्छी तरह से काम नहीं कर सकता है। यह बिल्कुल इस बात पर निर्भर करता है कि संकलक के किन चरणों के लिए लक्ष्य मानक के ज्ञान की आवश्यकता होती है और कौन सी अवस्थाएँ नहीं होती हैं और इसका प्रभाव उस अंतर-प्रक्रियात्मक अनुकूलन पर पड़ता है जो ऑब्जेक्ट फ़ाइलों को पार करता है। सौभाग्य से, जीसीसी, एलएलवीएम, और वीसी ++ अच्छी तरह से डिज़ाइन किए गए हैं और इस मुद्दे पर नहीं हैं (ऐसा नहीं है कि मुझे पता है)।

इसलिए, CCC मानक के विभिन्न संस्करणों में बाइनरी संगतता को सक्षम करने के लिए GCC, LLVM, और VC ++ को डिज़ाइन किया गया है । यह वास्तव में मानक स्वयं की आवश्यकता नहीं है, हालांकि।

वैसे, हालांकि वीसी ++ संकलक एसटीडी स्विच प्रदान करता है , जो आपको सी ++ मानक के एक विशेष संस्करण को लक्षित करने में सक्षम बनाता है, यह सी ++ 11 को लक्षित करने का समर्थन नहीं करता है। निर्दिष्ट किया जा सकता न्यूनतम संस्करण C ++ 14 है, जो Visual C ++ 2013 अपडेट 3 से शुरू होने वाला डिफ़ॉल्ट है। आप C ++ 11 को लक्षित करने के लिए VC ++ के पुराने संस्करण का उपयोग कर सकते हैं, लेकिन तब आपको विभिन्न VC ++ कंपाइलर का उपयोग करना होगा विभिन्न अनुवाद इकाइयों को संकलित करने के लिए जो C ++ मानक के विभिन्न संस्करणों को लक्षित करते हैं, जो बहुत कम से कम डब्ल्यूपीओ को तोड़ते हैं।

गुफा: मेरा उत्तर पूर्ण या बहुत सटीक नहीं हो सकता है।


सवाल वास्तव में संकलन के बजाय लिंकिंग की चिंता करने के लिए था। मैं पहचानता हूं ( इस टिप्पणी के लिए धन्यवाद ) जो शायद स्पष्ट नहीं था और इसे स्पष्ट करने के लिए इसे संपादित किया है कि किसी भी शामिल हेडर की तीनों मानकों में एक ही व्याख्या है।
रिकाब

@ricab उत्तर संकलन और लिंकिंग दोनों को शामिल करता है। मुझे लगा कि तुम दोनों के बारे में पूछ रहे हो।
हादी ब्रिस

1
वास्तव में, लेकिन मुझे लगता है कि इसका उत्तर बहुत लंबा और भ्रमित करने वाला है, खासकर जब तक "अब मैं लिंकर स्तर पर संगतता पर चर्चा करूंगा"। आप उपरोक्त सब कुछ को बदल सकते हैं जैसे कि यदि शामिल हेडर को C ++ 11 और C ++ 14/17 में समान अर्थ के लिए पोस्ट नहीं किया जा सकता है, तो उन्हें पहली जगह में शामिल करना सुरक्षित नहीं है । शेष भाग के लिए, क्या आपके पास ऐसा स्रोत है जो यह दर्शाता है कि वे तीन बुलेट पॉइंट असंगति के एकमात्र संभावित कारण हैं? किसी भी मामले में जवाब के लिए धन्यवाद, मैं अभी भी मतदान कर रहा हूं
रिकब

@ricab मैं निश्चित रूप से नहीं कह सकता। इसलिए मैंने जवाब के अंत में कैविएट जोड़ा। किसी और के जवाब को अधिक सटीक या पूर्ण बनाने के लिए किसी और का स्वागत करने का स्वागत है।
हादी ब्रिस

यह मुझे भ्रमित करता है: "एक ही संकलक का उपयोग करने का अर्थ है कि समान मानक पुस्तकालय हेडर और स्रोत फ़ाइलें (...) का उपयोग किया जाएगा"। ऐसा कैसे हो सकता है? अगर मेरे पास g5 के साथ संकलित पुराना कोड है, तो उस संस्करण से संबंधित 'कंपाइलर फाइलें' भविष्य का प्रमाण नहीं हो सकती हैं। अलग-अलग संकलक संस्करणों के साथ अलग-अलग समय पर (बेतहाशा) संकलित स्रोत कोड के लिए, हम यह सुनिश्चित कर सकते हैं कि लाइब्रेरी हेडर और स्रोत फ़ाइलें अलग-अलग हैं। अपने नियम के साथ कि ये समान होने चाहिए, आपको gcc5 के साथ पुराने स्रोत कोड को फिर से जोड़ना होगा, ... और सुनिश्चित करें कि वे सभी नवीनतम (समान) 'संकलक फ़ाइलों' का उपयोग करते हैं।
user2943111

2

नए C ++ मानक दो भागों में आते हैं: भाषा सुविधाएँ और मानक पुस्तकालय घटक।

जैसा कि आप नए मानक से मतलब रखते हैं , भाषा में परिवर्तन (उदाहरण के लिए-जैसे) के लिए लगभग कोई समस्या नहीं है (कभी-कभी नए मानक भाषा सुविधाओं के साथ 3 पार्टी लाइब्रेरी हेडर में संघर्ष मौजूद हैं)।

लेकिन मानक पुस्तकालय ...

प्रत्येक कंपाइलर संस्करण C ++ मानक लाइब्रेरी (libstdc ++ के साथ gcc, libc ++ के साथ क्लेंग, MS C ++ मानक लाइब्रेरी के साथ VC ++ ...) और बिल्कुल एक कार्यान्वयन के साथ आता है, प्रत्येक मानक संस्करण के लिए कई कार्यान्वयन नहीं। इसके अलावा कुछ मामलों में आप संकलित की तुलना में मानक पुस्तकालय के अन्य कार्यान्वयन का उपयोग कर सकते हैं। आपको जो ध्यान देना चाहिए वह एक पुराने मानक पुस्तकालय कार्यान्वयन को एक नए के साथ जोड़ रहा है।

3 पार्टी पुस्तकालयों और आपके कोड के बीच जो संघर्ष हो सकता है, वह मानक पुस्तकालय (और अन्य पुस्तकालय) है जो उस तीसरे पक्ष के पुस्तकालयों से जुड़ता है।


"प्रत्येक संकलक संस्करण एसटीएल के कार्यान्वयन के साथ आता है" नहीं वे
ऑर्बिट

@LightnessRacesinOrbit क्या आपका मतलब है कि उदाहरण के लिए libstdc ++ और gcc के बीच कोई तालमेल नहीं है?
ई। वैकिली

8
नहीं, मेरा मतलब है कि एसटीएल केवल बीस वर्षों से प्रभावी रूप से अप्रचलित है। आपका मतलब था C ++ Standard Library। शेष उत्तर के लिए, क्या आप अपना दावा वापस करने के लिए कुछ संदर्भ / साक्ष्य प्रदान कर सकते हैं? मुझे लगता है कि इस तरह के प्रश्न के लिए यह महत्वपूर्ण है।
ऑर्बिट

3
क्षमा करें, नहीं, यह पाठ से स्पष्ट नहीं है। आपने कुछ दिलचस्प दावे किए हैं, लेकिन अभी तक किसी भी सबूत के साथ उनका समर्थन नहीं किया है।
ऑर्बिट
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.