2012-01-28 25 views
6

"के कई परिभाषा" के साथ इस मुद्दे को लिंक मैं निम्नलिखित "स्थिरांक" शीर्षक है।संकलन त्रुटि

ध्यान दें कि मैं X.h या Y.h में शामिल हूं।

फ़ाइलें X.c और Y.c ऑब्जेक्ट फ़ाइलों में संकलित हो जाएं जो libXY.a नामक एक स्थिर लाइब्रेरी में संग्रहीत हैं।

जब मैं X.h और Z.h में Y.h, शामिल हैं और जब मैं libXY.a से लिंक, मैं त्रुटियों के बिना Z.c संकलन नहीं कर सकते हैं:

/* Z.h */ 

#include "X.h" 
#include "Y.h" 

मैं निम्नलिखित संकलन त्रुटियों जब Z.c संकलित करने के लिए कोशिश कर रहा है:

/path/to/libXY.a(X.o):(.data+0x0): multiple definition of `kFoo` 
/path/to/libXY.a(Y.o):(.data+0x0): first defined here 
/path/to/libXY.a(X.o):(.data+0x8): multiple definition of `kBar` 
/path/to/libXY.a(Y.o):(.data+0x8): first defined here 

मैंने kFoo और kBar से extern पर सेट करने का प्रयास किया है, लेकिन वह मदद नहीं करता है।

मैं कई परिभाषाओं को कैसे हल करूं, जब मैं केवल एक बार स्थिरांक (हेडर गार्ड #ifndef CONSTANTS_H के माध्यम से) समेत हूं?

+0

शायद नहीं तत्काल मुद्दा (यकीन नहीं), लेकिन आप को निकाल देना चाहिए फर्जी '#pragma एक बार' और अपने शीर्षलेख में उचित बहु-समावेश गार्ड रखो। मानक प्रारूप '#ifndef MYHEADER_H #define MYHEADER_H है .... # endif' –

उत्तर

9

मैं कैसे कई हल होगा परिभाषाएं, जब मैं केवल एक बार स्थिरांक समेत हूं (हेडर गार्ड #ifndef CONSTANTS_H के माध्यम से)?

इस के साथ

constants.h में:

const char * kFoo = "foo"; 

kFoo के लिए एक परिभाषा हर अनुवाद कि #include रों constants.h में उत्सर्जित कर दिया जाएगा। इस प्रकार, कई परिभाषाएं, जिसके परिणामस्वरूप लिंक त्रुटियां होती हैं।

asaelr के रूप में उल्लेख किया (+1), आप इसे इस तरह का समाधान होगा:

constants.h

extern const char* const kFoo; 

स्थिरांक।ग

const char* const kFoo = "foo"; 

(ध्यान दें कि मैं भी सूचक स्थिरांक है, जो आम तौर पर है क्या आप इस मामले में क्या करना चाहते हैं बनाया)

+4

कुछ अन्य विकल्प हैं जिन्हें माना जा सकता है। वर्तमान संदर्भ में, आपने जो सुझाव दिया है वह सही है, लेकिन: (ए) 'स्थिर कॉन्स char * kfoo =" foo ";' एक अलग constants.c फ़ाइल के बिना काम करेगा; और (बी) 'स्थैतिक कॉन्स चार kFoo [] = "foo"; '32-बिट बनाम 64-बिट पॉइंटर्स के आधार पर, जो आवश्यक है (और 4 या 8 बाइट्स कम जगह का उपयोग किया जाता है) का एक और सटीक प्रतिपादन हो सकता है; और (सी) 'बाहरी कॉन्स चार केएफयू []; 'प्लस constants.c युक्त' const char kfoo [] =" foo ";' आपके समाधान का उचित भिन्नता हो सकता है। कोड को शायद 'kFoo = "pqr"; 'करने की अनुमति नहीं दी जानी चाहिए। –

+0

@ जोनाथन लेफ्लर +1 मैंने वास्तव में बदलावों के बारे में लिखना शुरू किया जो कि इस परिदृश्य में फॉलो अप एडिट में बनाया जा सकता था, लेकिन मेरे संपादन को छोड़ दिया क्योंकि इस साइट पर मैं और अन्य ने पहले से ही ऐसा किया है। मुझे लगता है कि 'बाहरी कॉन्स char * const kfoo;' आम तौर पर एक स्ट्रिंग स्थिरांक से निपटने वाले दस्तावेज़/घोषित करने के लिए स्पष्ट रूप से स्पष्ट तरीका है (सी का उपयोग करना)। बेशक, यह व्यक्तिपरक है। ए + बी) काम करेगा, लेकिन बाइनरी ब्लोट में परिणाम हो सकता है। constants.h + 'k' उपसर्ग सुझाव देता है कि यह एक ओएसएक्स या आईओएस प्रोजेक्ट है (यह अक्सर पीएच में समाप्त होता है)। 'बाहरी' आमतौर पर उस परिदृश्य में संकलन और लिंकिंग के लिए सबसे सरल है। – justin

+0

जब तक आपको वास्तव में एक पॉइंटर और स्ट्रिंग की आवश्यकता नहीं होती है, तब तक पॉइंटर नोटेशन को वरीयता में सरणी नोटेशन का उपयोग करें। मैं मानता हूं कि स्थैतिक संस्करण कोड ब्लोट का कारण बन सकते हैं और आमतौर पर इसकी अनुशंसा नहीं की जाती है। (पॉइंटर संस्करण कोड ब्लोएट का कारण बनता है, जो लगातार एक सूचक के आकार के द्वारा निष्पादन योग्य को बढ़ाता है।) –

4

आपको हेडर फ़ाइल में चर परिभाषित नहीं करना चाहिए। उन्हें स्रोत फ़ाइलों में से एक में परिभाषित करें, और हेडर फ़ाइल में उन्हें (extern) घोषित करें।

(आप ने लिखा है "मैं निर्वासन को kFoo और kbar स्थापित करने की कोशिश की है, लेकिन यह मदद नहीं करता है।" मुझे लगता है कि है कि आप उन्हें एक स्रोत फ़ाइल में परिभाषित नहीं किया)

+0

यदि मैं' constants.c' में चर को परिभाषित करता हूं, तो मुझे लाइब्रेरी संकलित करते समय "kfoo'" त्रुटियों को अनिर्धारित संदर्भ मिलता है। (मैं 'constants.c' को 'constants.o' में संकलित कर रहा हूं और इसे पुस्तकालय के साथ भी शामिल कर रहा हूं।) कोई विचार? –

+0

क्या आपने इसे परिभाषित या घोषित किया था? आप इसे कैसे लिंक करते हैं? – asaelr

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