2010-04-06 10 views
5

पृष्ठभूमि:.h फ़ाइलों को संशोधित किए बिना मैक्रो रेडिफ़िनेशन को संभालना ... सी/सी ++ भाषा

मान लें कि मेरे पास दो शीर्षलेख फ़ाइलें हैं a.h और b.h।

a.h शामिल हैं:

#define VAR 1 

b.h शामिल हैं:

#define VAR 2 

नोट: मैक्रो दोनों का नाम एक ही है। मान लें कि मेरे पास कुछ फ़ाइल myFile.c है जिसमें दोनों शीर्षलेख फ़ाइलें i.e. a.h और b.h शामिल हैं।

जब मैं VAR तक पहुंचने का प्रयास करता हूं, तो मुझे VAR की पुनर्वितरण त्रुटि मिलती है।

इस समस्या को हल करने के लिए, मैंने इस त्रुटि को रोकने के लिए a.h और b.h फ़ाइलों दोनों में #ifndef VAR कथन डाला। हेडर फाइल कई मैक्रो, न सिर्फ एक मैक्रो हो सकते हैं: a.h फ़ाइल

#ifndef VAR 
    #define VAR 1 
#endif 

b.h फ़ाइल हो जाता है

#ifndef VAR 
    #define VAR 2 
#endif 

नोट हो जाता है।

समस्या:

मान लेते हैं कि a.h और b.h फ़ाइलें तृतीय पक्ष पुस्तकालय से प्राप्त कर रहे हैं। इन फ़ाइलों में #ifndef VAR कथन शामिल नहीं है।

मुझे अपनी शीर्षलेख फ़ाइलों को बदलने की अनुमति नहीं है।

क्या मैं myFile.c या myFile.cpp फ़ाइल में मैक्रो 'VAR' redefinition त्रुटि को हल कर सकता हूं जो VAR मैक्रो का उपयोग करता है?

मुझे पता है कि मैं #undef VAR का उपयोग मैक्रो VAR को परिभाषित करने के लिए किया जा सकता है। मैं अपने प्रोग्राम में बाद में VAR को चुनिंदा कैसे कर सकता हूं? यानी myFile.c कोड की लाइन 10 पर, मैं अपने कोड के लाइन 15 पर, एएच फ़ाइल से VAR परिभाषा को संदर्भित करने में सक्षम होना चाहिए, मुझे बीएच फ़ाइल से VAR को संदर्भित करने में सक्षम होना चाहिए और लाइन 18 पर फिर से संदर्भित होना चाहिए आह फ़ाइल से VAR करने के लिए।

संक्षेप में, क्या मैं मैक्रो पॉलीमोर्फिज्म करने में सक्षम हूं? हेडर फ़ाइल का नाम दिया गया है, इसे उस फ़ाइल में मौजूद मैक्रो परिभाषा का संदर्भ लेना चाहिए।

मैंने किसी समस्या को हल करने के लिए नेमस्पेस चाल का उपयोग करने के बारे में सोचा था। नेमस्पेस में पहले हेडर फ़ाइल को पहले और दूसरी हेडर फ़ाइल को नेमस्पेस सेकेंड में परिभाषित करें।

मैं दो नामस्थान को परिभाषित करने की कोशिश की। पहले नेमस्पेस में # शामिल है एएच और दूसरा नेमस्पेस बीएच है। हालांकि, नामस्थान चाल मैक्रो के साथ काम नहीं करती है। जब मैंने फर्स्टन्स :: VAR तक पहुंचने का प्रयास किया, तो कंपाइलर एक त्रुटि संदेश रिपोर्ट करता है।

क्या आप कृपया कुछ सुझाव सुझा सकते हैं?

उत्तर

4

आप अपनी समर्पित हेडर फाइलों के माध्यम से हमेशा समस्याग्रस्त शीर्षलेख फ़ाइलों को शामिल कर सकते हैं, जहां आप आवश्यक #ifdef, #undef इत्यादि को पुनर्वितरण त्रुटियों को रोकने के लिए मैक्रोज़ जोड़ सकते हैं। जैसे

wrapperToA.h 
----- 
#ifdef VAR 
    #undef VAR 
#endif 

#include "a.h" 

अद्यतन: @Vlad इस बीच में पूर्ण समाधान बाहर काम किया - उसे (और +1 :-)

+0

यह करता है ओपीएस जवाब नहीं है 'V'' की 'ए' या' बी 'की परिभाषा का एक-दूसरे से उपयोग करने के लिए ईमानदारी से उपयोग किया जाता है। – vladr

7

मैक्रो विस्तार preprocessor स्तर पर होता है और उपयोग नाम स्थान के लिए अभेद्य है करने के लिए प्रशंसा।

क्या सभी मैक्रोज़ जिन्हें आप सरल स्थिरांक का उपयोग करना चाहते हैं, token concatenation आदि में उपयोग नहीं किया जाता है?

यदि हां, तो आप की तरह कुछ कोशिश कर सकते हैं पूर्वप्रक्रमक/संकलक की खाई को पाटने और VAR आदि, दोनों A और B परिभाषाओं के लिए उपयोग बनाए रखने के लिए निम्नलिखित अगर यह अपनी स्थिति सूट:

// ab_wrapper.h 
#include <a.h> 
static const int A_VAR1 = VAR1; 
static const char* A_VAR2 = VAR2; 
#undef VAR1 
#undef VAR2 

#include <b.h> 
static const int B_VAR1 = VAR1; 
static const char* B_VAR2 = VAR2; 

// code.c 
#include <ab_wrapper.h> 
... 
int x = A_VAR1; 
int y = B_VAR1; 
... 
+0

यह मैक्रोज़ के लिए काम करता है जो निरंतर परिभाषित करता है। मैक्रोज़ के लिए क्या करना है जो कुछ मूल्यों की गणना करता है? क्या हम ऐसे मैक्रोज़ के लिए इनलाइन फ़ंक्शन लिख सकते हैं और फिर उन मैक्रोज़ को अनदेखा कर सकते हैं? – user310119

+0

@ user310119, हाँ, बिल्कुल। – vladr

0

पीटर टोरोक के जवाब पर विस्तार करने के लिए।

आमतौर पर तीसरे पक्ष के घटकों को लपेटना एक अच्छा विचार है।

  • स्वयं के हैडर, जो (अपने स्वयं के टोकन के आधार पर कुछ preprocessing टोकन को परिभाषित करने या अपरिभाषित दूसरों उदाहरण के लिए)
  • एक हल्के बनाने के लिए विकल्पों को नियंत्रित करने के लिए अनुमति देता है में हेडर लपेटकर:

    कई चरण हैं मुखौटा लाइब्रेरी जो संभावित रूप से खतरनाक तरीकों को छिपाने के लिए ख्याल रखती है, यदि आवश्यक हो तो उन्हें म्यूटेक्स के साथ लपेटें आदि ... और अन्यथा केवल विवरण छुपाएं ताकि कोई भी परिवर्तन आपके सभी कोड बेस पर नहीं हो सके।

आप पहले वक्तव्य में अधिक रुचि रखते हैं, जो कि सबसे आम है। बस उन्हें लपेट:

// wrapper/a.h 
#ifdef VAR 
#undef VAR 
#endif // ifdef VAR 

#include <3rdparty/a.h> 

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

तथापि प्रभाव आप ध्यान से समीक्षा करनी चाहिए कि का सवाल है ...

// 3rdparty/a.h 
#define VAR 1 

// 3rdparty/aa.h 
#include "a.h" 
typedef int IntArray[VAR]; 

// 3rdparty2/b.h 
#define VAR 2 

यह निश्चित रूप से और अधिक जटिल :) तुम भी undef के साथ "aa.h" रैप करने के लिए इस मुद्दे को बचने की जरूरत है ...

और निश्चित रूप से, इसका मतलब है आप VAR पर अपने आप को अपने कोड में कहीं भी भरोसा बेहतर नहीं के बाद से आप जानते हैं कि इसकी परिभाषा जिस क्रम में आप शीर्ष लेख शामिल आधार पर बदल सकता है चाहता हूँ ...

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

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