Tuesday, 15 September 2015

c++ - Same symbols in different libraries and linking order -


मेरे पास 2 पुस्तकालय हैं: test.1 और test.2 । दोनों पुस्तकालयों में एक एकल वैश्विक extern "c" void f (); फ़ंक्शन है, विभिन्न कार्यान्वयन के साथ (सिर्फ एक cout परीक्षण के लिए)

मैंने निम्नलिखित परीक्षण किया:

टेस्ट 1 डायनेमिक लिंकिंग: अगर मैं libtest.1.so और फिर libtest.2.so निष्पादन योग्य के makefile में और फिर f (); में मुख्य , libtest.1 .so- & gt; f () कहा जाता है।
अगर मैं मेसेफाइल में आदेश बदलता हूं, तो libtest.2.so- & gt; f () को

कहा जाता है >

टेस्ट 2 स्टेटिक लिंकिंग: बिल्कुल स्थिर पुस्तकालयों के साथ ऐसा होता है

टेस्ट 3 डायनेमिक लोडिंग
लाइब्रेरी के रूप में मैन्युअल रूप से लोड किया गया है, सब कुछ अपेक्षित रूप से काम करता है।


मुझे कई परिभाषाओं के लिए एक त्रुटि की उम्मीद थी, जो जाहिर नहीं हुआ।

इसके अलावा, यह एक-परिभाषा-नियम को तोड़ता नहीं है, जैसा कि स्थिति अलग है।

यह भी निर्भरता-नरक नहीं है (यह इससे संबंधित नहीं है) , और न ही किसी भी प्रकार के असफलता ..

तो, यह क्या है? अपरिभाषित व्यवहार? अनिर्दिष्ट व्यवहार? या यह वास्तव में लिंक करने के आदेश पर निर्भर करता है?

और क्या ऐसी स्थितियों को आसानी से पहचानने का कोई तरीका है?


संबंधित प्रश्न:



संपादित करें मैंने दो और परीक्षण किए, जो इस यूबी की पुष्टि करते हैं:

मैंने एक दूसरा फ़ंक्शन जोड़ा शून्य जी () में test.1 और NOT में test.2

गतिशील लिंकिंग और का उपयोग कर। < / Code> libs, ऐसा ही होता है - f को उसी तरीके से कहा जाता है, g भी निष्पादन योग्य है (अपेक्षित रूप से)।

लेकिन स्थिर अब जोड़ने से चीजों में बदलाव होता है: यदि test.1 है से पहले test.2 , कोई त्रुटि नहीं है, दोनों कार्यों से परीक्षण 1 को कहा जाता है।
लेकिन जब ऑर्डर बदल जाता है, तो "कई परिभाषाएं" त्रुटि आती है।

यह स्पष्ट है, "कोई निदान आवश्यक नहीं है" (@ मार्कब का उत्तर देखें), लेकिन यह "अजीब" जो कभी-कभी त्रुटि होती है, कभी-कभी - यह नहीं है।

फिर भी, इसका जवाब बहुत स्पष्ट है और बताता है सब कुछ ऊपर - यूबी।

यह बिल्कुल एक परिभाषा नियम का उल्लंघन करता है मामलों 1 और 2 3 के मामले में, जब आप स्पष्ट रूप से यह निर्दिष्ट करते हैं कि यह कार्यान्वित करने के लिए फ़ंक्शन का कौन सा संस्करण हो सकता है या नहीं। ओडीआर का उल्लंघन अनिवार्य व्यवहार है, कोई नैदानिक ​​आवश्यकता नहीं है।

3.2 / 3:

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


No comments:

Post a Comment