लिंक करते समय इनलाइन फ़ंक्शंस की एकाधिक परिभाषा मेरे पास एक सी ++ प्रोग्राम है जिसे मैं mingw (विंडोज़ के लिए जीसीसी) के साथ संकलित करता हूं। Mingw के टीडीएम रिलीज का उपयोग जिसमें जीसीसी 4.4.1 शामिल है। दो स्थैतिक पुस्तकालय (.a) फ़ाइलों के निष्पादन योग्य लिंक: उनमें से एक सी में लिखी एक तृतीय पक्ष पुस्तकालय है; दूसरा एक सी ++ लाइब्रेरी है, जो मेरे द्वारा लिखी गई है, जो सी लाइब्रेरी का उपयोग करती है, शीर्ष पर अपना स्वयं का सी ++ एपीआई प्रदान करती है।स्थैतिक libs
सी (लाइब्रेरी की कार्यक्षमता के मेरे दृश्य में, अत्यधिक) भाग इनलाइन फ़ंक्शंस में लागू किया गया है। जब आप सी लाइब्रेरी के एपीआई का उपयोग करते हैं तो आप इनलाइन फ़ंक्शंस को शामिल नहीं कर सकते हैं, लेकिन जब मैं इसे सभी को एक साथ जोड़ने का प्रयास करता हूं, तो मुझे लिंक त्रुटियां मिल रही हैं कि सभी इनलाइन फ़ंक्शंस की एक से अधिक परिभाषा है - मेरे पास दोनों मेरे सी ++ रैपर लाइब्रेरी में और जिन्हें मैंने नहीं किया है, मूल रूप से हेडर में परिभाषित इनलाइन में कुछ भी सी लाइब्रेरी और सी ++ लाइब्रेरी दोनों में इसके लिए एक फ़ंक्शन बनाया गया है।
यह एकाधिक परिभाषा त्रुटियों का कारण नहीं बनता है जब फ़ाइलों को एक ही प्रोजेक्ट में अलग-अलग .c या .cpp फ़ाइलों में कई बार उपयोग किया जाता है; समस्या यह है कि यह पुस्तकालय प्रति एक परिभाषा उत्पन्न करता है।
दोनों पुस्तकालयों में इन इनलाइन फ़ंक्शंस के लिए कंपाइलर जनरेटिंग फ़ंक्शंस और प्रतीक कैसे/क्यों हैं? मैं इसे अपने कोड में उत्पन्न करना बंद करने के लिए कैसे मजबूर कर सकता हूं? क्या कोई उपकरण है जो मैं .a फ़ाइल से डुप्लिकेट फ़ंक्शंस को पट्टी करने के लिए चला सकता हूं, या लिंकर को कई परिभाषाओं को अनदेखा करने का एक तरीका है?
(एफवाईआई, तीसरी पार्टी लाइब्रेरी में #ifdef __cplusplus और बाहरी "सी" गार्ड अपने सभी शीर्षकों में शामिल हैं; वैसे भी अगर यह समस्या थी, तो यह प्रतीक की एक एकाधिक परिभाषा नहीं पैदा करेगा, इससे विपरीत समस्या होगी क्योंकि प्रतीक अपरिभाषित या कम से कम अलग होगा।)
विशेष रूप से, लिंक त्रुटियां तब नहीं होती हैं जब मैं तृतीय पक्ष सी लाइब्रेरी के DLL से लिंक करता हूं; हालांकि मुझे अजीब रनटाइम विफलताओं मिलती हैं जो कि मेरे कोड के साथ अपने कार्यों के संस्करण के साथ करना पड़ता है, इसे डीएलएल से कॉल करना चाहिए। (जैसे कि कंपाइलर फ़ंक्शंस के स्थानीय संस्करण बना रहा है, मैंने नहीं पूछा था।)
इस प्रश्न के समान संस्करणों से पहले पूछा गया है, हालांकि, मुझे इनमें से किसी भी स्थिति में मेरी स्थिति का उत्तर नहीं मिला:
इस सवाल का जवाब था कि पोस्टर गुणा चर को परिभाषित किया गया था, मेरी समस्या इनलाइन कार्यों के कई परिभाषा है: Repeated Multiple Definition Errors from including same header in multiple cpps
यह एक MSVC कार्यक्रम था, लेकिन मैं MinGW उपयोग कर रहा हूँ; भी, इस सवाल में पोस्टर की समस्या एक शीर्षक में वर्ग शरीर के बाहर वर्ग निर्माता एक सी की ++ परिभाषा था, जबकि मेरी समस्या सी कार्यों कि इनलाइन हैं के साथ है: Static Lib Multiple Definition Problem
इस मूर्ख सी के रूप में अपने सभी सी कोड नाम दिया ++ Multiple definition of lots of std:: functions when linking
यह एक सिर्फ जानना क्यों एक परिभाषा नियम का उल्लंघन करने में कोई त्रुटि नहीं था चाहता था: सुरक्षित - फ़ाइलें और उसकी सी कोड सी ++ नहीं था unpredictable behavior of Inline functions with different definitions
सूचना है कि C99 इनलाइन अर्थ विज्ञान सी के ++ एक से अलग हैं नहीं: सी में , यदि इनलाइन फ़ंक्शन घोषणाओं में से एक स्पष्ट रूप से 'बाहरी' निर्दिष्ट किया गया है, तो यह बाहरी परिभाषा बनाता है - जो अब एक इनलाइन परिभाषा नहीं है। ये बाहरी परिभाषा कार्यक्रम में कई बार प्रकट नहीं हो सकती हैं। सी ++ में इस तरह के फ़ंक्शन पर एक स्पष्ट 'बाहरी' का कोई प्रभाव नहीं पड़ता है। सी –
में 'स्थैतिक इनलाइन' करने के साथ आप सबसे अच्छे हैं। आम तौर पर इनलाइन फ़ंक्शन परिभाषाओं को 'कमजोर' प्रतीक के रूप में चिह्नित किया जाता है और लिंकर को सभी डुप्लिकेट को ही हटा दिया जाता है। – Omnifarious
धन्यवाद जोहान्स: प्रीप्रोसेसर परिभाषाओं का उपयोग करते हुए, सी लाइब्रेरी की हेडर फाइलें इन कार्यों को "इनलाइन" घोषित करती हैं यदि सी लाइब्रेरी की .c फाइलों में और "बाहरी इनलाइन" जब वे मेरे प्रोजेक्ट में हों। लेकिन मुझे यकीन नहीं है कि उन्होंने ऐसा क्यों किया। सी लाइब्रेरी में कुछ कोड है जो एक फ़ंक्शन के पते को अद्वितीय कुंजी मान के रूप में उपयोग करता है। एक सी ++ प्रोग्रामर के रूप में मैं देखता हूं कि खराब अभ्यास के रूप में और मैं वास्तव में प्रार्थना करता हूं कि उन्होंने इस तरह के इनलाइन फ़ंक्शन के पते का उपयोग नहीं किया। मुझे लगता है कि इन टिप्पणियों के बीच उत्तर देने के लिए लगभग पर्याप्त जानकारी है, हालांकि मैं अभी भी प्रोग्राम को संकलित नहीं कर सकता। – Dennis