2011-05-24 26 views
17

मैं एक C++ प्रोग्राम है जो पहले से संकलित है, लेकिन Jamfiles के साथ mucking के बाद, कार्यक्रम अब संकलित और ld एक duplicate symbol error उत्सर्जित की उत्पत्ति को समझना। यह क्रमिक मूल Jamfiles पर वापस लौट रहा, bjam clean चल रहा है, हाथ से वस्तुओं को दूर करने, और जीसीसी सामने अंत के साथ बजना MacOS 10.6.7 पर 4.2.1 जीसीसी से स्विच करने के बाद बनी रही।एक लिंकर डुप्लिकेट प्रतीक त्रुटि

कार्यक्रम का एक सरलीकृत वर्णन है कि वहाँ main.cpp और चार फ़ाइलें, a.h,cpp और b.h,cpp है, जो एक स्थिर पुस्तकालय जो main.o से जुड़ा हुआ है में संकलित कर रहे हैं। दोनों, main.cpp और b.cpp हमलावर प्रतीक, off.h, दो अलग अलग मध्यवर्ती फ़ाइलों के माध्यम से युक्त फ़ाइल पर निर्भर करते हैं, लेकिन न तो a.h है और न ही a.cppoff.h पर किसी भी तरह से निर्भर करते हैं।

इससे पहले कि आप से पूछते हैं, मुझे यकीन है कि सभी फाइलों को कई परिभाषा गार्ड (#ifndef, #define, #endif) में लिपटे रहे थे, और जब मैं एक फ़ाइल है कि उन्हें याद कर रहा था मिला, यह संदर्भ नहीं दिया था off.h। इससे भी महत्वपूर्ण बात, b.h कुछ भी संदर्भ off.h, केवल कार्यान्वयन, b.cpp शामिल नहीं है, off.h के लिए किसी भी संदर्भ बनाता है। यह अकेला मुझे परेशान था।

की उम्मीद के रूप में मेरे भ्रम को जोड़ने के लिए, मैं b.cpp से off.h का संदर्भ निकालें करने में सक्षम था और, इसे सफलतापूर्वक कंपाइल। हालांकि, जब मैंने संदर्भ को वापस जोड़ा, तो इसे सफलतापूर्वक संकलित किया गया, और ऑब्जेक्ट फ़ाइलों को साफ़ करने के बाद ऐसा करना जारी रखा। मैं अभी भी क्यों यह संकलन करने में विफल रहा था के लिए एक नुकसान में हूँ, विशेष रूप से विचार कर रहा है कि प्रतीकों विरोध हुआ, मैं रोका था प्रतीक दोहराव नहीं होना चाहिए, और मैं किसी भी पूर्व/अधूरा बनाता कमाई से छुटकारा पा लिया था।

जब से मैं सफलतापूर्वक मेरी कार्यक्रम को संकलित करने में सक्षम था, मुझे शक है मैं इसे पुन: पेश करने किसी भी सुझाव का परीक्षण करने में सक्षम हो जाएगा। हालांकि, मैं यह कैसे हो सकता है के रूप में उत्सुक हूँ, और अगर मैं भविष्य में इस व्यवहार के पार चला, क्या है, यह तय करने के लिए अगर मैं क्या किया है परे कुछ भी, मैं क्या कर सकता है?

+7

आपको एक त्रुटि तुम अपने आप को पुन: पेश नहीं कर सकते निदान करने के लिए हमें उम्मीद कर रहे हैं? –

+0

@Neil, ऐसा नहीं है। नोट: जब तक मैं एक "समाधान" सूझा संकलन में कई प्रयास के लिए इस समस्या को पुन: पेश करने में सक्षम था। और, मैं उम्मीद करता हूं कि समस्या फिर से दिखाई देने वाली समस्या के कारण कंक्रीट की तुलना में अधिक सैद्धांतिक नहीं है। हालांकि, मैं क्या कारण हो सकता है एक प्रतीक संघर्ष करने के लिए दो अलग-अलग संकलन इकाइयों में संदर्भित जब कोई विवाद मौजूद होना चाहिए का एक बेहतर समझ हासिल करने के लिए कोशिश कर रहा हूँ।और क्या, अगर कोई है, तो समस्या का निदान और कम करने के लिए मैं अतिरिक्त कदम उठा सकता हूं। – rcollyer

+1

मैं इसे 90% मौका दूंगा जो वास्तव में, वास्तव में, सभी ऑब्जेक्ट फ़ाइलों को साफ़ नहीं करता है (शायद libtool या कुछ उन्हें एक छिपी निर्देशिका में छुपा रहा था?)। फिर भी, यदि आप इसे पुन: पेश नहीं कर सकते हैं, तो इसके निचले हिस्से तक पहुंचने का कोई तरीका नहीं है। – bdonlan

उत्तर

39

इस बार नहीं बल्कि केवल यह घोषित करने की तुलना में एक हेडर फाइल में एक वस्तु को परिभाषित करने, का परिणाम है। पर विचार करें:

परम पूज्य:

#ifndef H_H_ 
#define H_H_ 
int i; 
#endif 

a.cpp:

#include "h.h" 

b.cpp:

#include "h.h" 
int main() {} 

यह कोई डुप्लिकेट का उत्पादन करेगा प्रतीक iextern int i; और वास्तव में स्रोत-कोड फ़ाइलों में से एक में यह परिभाषित करने के लिए: int i; समाधान हेडर फाइल में वस्तु घोषित करने के लिए है।

+2

प्रतीक हेडर में इनलाइन घोषित एक फ़ंक्शन था, लेकिन कीवर्ड 'इनलाइन' की कमी थी जो [यह] (http://stackoverflow.com/questions/2954256/duplicate-symbol-linker-error-c-help) सुझा सकता है आवश्यक होना। लेकिन, आपके समाधान पर मेरा प्रश्न यह है कि 'int i' ऑब्जेक्ट फ़ाइल' a.o' में इस तरह से खुलासा क्यों किया गया है कि यह 'b.o' में मिले किसी के साथ संघर्ष करता है? जहां तक ​​मैं इसे समझ गया, ऐसा नहीं होना चाहिए। मैं क्या खो रहा हूँ? – rcollyer

+2

1) फ़ाइल स्कोप पर घोषित नाम बाहरी संबंध हैं। 2) एकाधिक ऑब्जेक्ट एकजुट में एक वस्तु घोषित की जा सकती है, लेकिन इसे एक बार परिभाषित किया जाना चाहिए। –

+0

जितना अधिक मैं इस बारे में सोचता हूं, उतना ही ऐसा लगता है कि यह बहुत अच्छा कारण हो सकता है। जब तक मैं इसे दोहराना नहीं कर सकता, फिर भी, मैं एक दिन संकलित क्यों नहीं हुआ, बल्कि अगले दिन क्यों परेशान रहूंगा। – rcollyer

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