2016-01-13 11 views
14

के साथ एक (केवल पढ़ने के लिए तीसरे पक्ष के) शीर्षक lib.h पर विचार करें:सी प्रीप्रोसेसर मैक्रो का नाम कैसे बदलें?

#define XYZ 42 

एक स्रोत फ़ाइल में, मैं एक असंबंधित प्रयोजन के लिए शब्द XYZ उपयोग करना चाहते हैं, और करते 42 साथ प्रतिस्थापन नहीं चाहते हैं। लेकिन, एक ही स्रोत फ़ाइल में, अन्य प्रयोजनों के लिए, मैं से lib.h से बिना हार्डकोडिंग के मूल्य तक पहुंच बनाना चाहता हूं। मैं का नाम बदल सकता हूं XYZ से मैक्रो, LIB_XYZ कहां से?

निम्नलिखित काम नहीं करता है, क्योंकि पूर्वप्रक्रमक समय LIB_XYZ प्रतिस्थापन किया जाता है पर XYZ चाहता है, लेकिन XYZ अपरिभाषित किया गया था:

#include "lib.h" 
#define LIB_XYZ XYZ 
#undef XYZ 

वहाँ एक रास्ता अपने अंतिम करने के लिए LIB_XYZ के विस्तार में पूर्वप्रक्रमक चाल करने के लिए है XYZ से पहले मूल्य खो गया है?

+2

मुझे लगता है कि आप अटक गए हैं, अगर आप तीसरे पक्ष के शीर्षलेख फ़ाइल से LIB_XYZ की परिभाषा प्राप्त करना चाहते हैं, और सी कंपाइलर के अलावा कुछ भी उपयोग नहीं करना चाहते हैं। अगर मुझे ऐसा करना पड़ा, तो शायद मैं lib.h को our_lib.h में बदलने के लिए एक स्क्रिप्ट लिखूंगा, चयनित # परिभाषित संशोधित के साथ, मेरे कोड को our_lib.h शामिल करें, और सही बनाने के लिए मेकफ़ाइल का उपयोग करें यदि lib बदल गया –

+1

शायद [यह] (http://stackoverflow.com/questions/1793800/can-i-redefine-a-c-macro-then-define-it-back) मदद कर सकता है। –

उत्तर

6

प्री-प्रोसेसर के साथ नहीं, कम से कम, मुझे पता नहीं है कि मुझे पता है।

हालांकि, आपके उदाहरण में ज्ञात प्रकार के साथ सरल स्थिरांक के लिए, एक कामकाज है।

#include <stdio.h> 

// <xyz.h> 

#define XYZ 42 

// </xyz.h> 

enum xyz_constants 
{ 
    LIB_XYZ = XYZ, 
}; 

#undef XYZ 

#define XYZ 27 

int 
main() 
{ 
    printf("old value: %d, new value: %d\n", LIB_XYZ, XYZ); 
    return 0; 
} 

नहीं stdio.h से फुलाना दिखा रहा है, इस कोड को पूर्व संसाधित निम्नलिखित है।

enum xyz_constants 
{ 
    LIB_XYZ = 42, 
}; 

int 
main() 
{ 
    printf("old value: %d, new value: %d\n", LIB_XYZ, 27); 
    return 0; 
} 

आप इसे अन्य डेटा प्रकारों और कुछ फ़ंक्शन-जैसे मैक्रोज़ के लिए कुछ डिग्री तक बढ़ा सकते हैं लेकिन निश्चित रूप से सीमाएं हैं।

वैसे भी, आपको विशेष पहचानकर्ता XYZ क्यों चाहिए? क्या आप अपने मैक्रो के लिए एक अलग नाम का उपयोग नहीं कर सकते?

+1

enum चाल शानदार था! धन्यवाद! पुन: क्यों XYZ एक और तीसरे पक्ष के मैक्रो का एक सबस्ट्रिंग है जिसे मैं संयोज के माध्यम से बना रहा हूं, और कॉन्सटेनेशन मैक्रो सामान्य है (एक्सवाईजेड या एबीसी या जो भी हो) के लिए काम करता है, इसलिए एक्सवाईजेड के साथ अटक गया। – alexei

+0

इस समाधान ने अभी मुझे बचाया :) – MByD

0

एक और .c फ़ाइल का उपयोग करें, और एक वैश्विक चर के लिए मैक्रो मान असाइन करें।

4

तो XYZlib.h से एक संख्या [या एक किस्म की एक निरंतर], आप इस्तेमाल कर सकते हैं एक enum है:

enum { LIB_XYZ = XYZ }; 
#undef XYZ 

तो XYZ ऊपर नहीं है, तो आप बनाने के लिए (जैसे) myxyz.c करता है कि lib.h शामिल नहीं है और वहाँ XYZ का उपयोग करें (अन्य फ़ाइलों शामिल हो सकते हैं xyz.h)

अंतर यह है कि #define LIB_XYZ XYZनहीं कि लाइन पर समाधान हो जाएगा केवल जब आप इसे बाद में उपयोग करते हैं, के रूप में:

foo(LIB_XYZ); 

ताकि क्योंकि आप पहले से #undef'edXYZ है काम नहीं करेगा।

0

एक प्रीप्रोसेसर प्रतीक एक नाम है। सामग्रियों को संरक्षित करते समय कोई प्रीप्रोसेसिंग निर्देश नहीं है जो नाम बदलता है।उदाहरण के लिए, यह देखते हुए या तो:

#define FOO 42 

या

#define FOO(x, y) x ## y (

एक मैक्रो BAR जो एक ही सामग्री है कहा जाता है, इन परिभाषाओं को दोहराए बिना परिभाषित करने के लिए कोई तरीका नहीं है।

#alias BAR FOO // nonexistent fantasy macro-cloning preprocessor directive 

और न ही इस तरह::

#define BAR FOO // for the #define FOO 42 case 

यह एक उपनाम नहीं है:

#rename BAR FOO // like #alias BAR FOO followed by #undef FOO 

अगर हम ऐसा करते हैं यही कारण है कि जैसे कोई आपरेशन नहीं है कहने के लिए है। मैक्रो BAR इस तरह परिभाषित किया गया है कि इसके प्रतिस्थापन टोकन अनुक्रम टोकन FOO है, और 42 नहीं है। यदि FOO मैक्रो गायब हो जाता है, तो BAR इसका अर्थ खो देता है।

भी ध्यान रखें कि सी पूर्वप्रक्रमक मैक्रो पूर्व प्रसंस्करण निर्देशों में विस्तार नहीं कर सकते, तो निम्न दृष्टिकोण भी काम नहीं करेगा:

// wrong: 
#define MACRO_DEFINER(NAME) \ 
    #define NAME 42 

MACRO_DEFINER(FOO) // hoping for #define FOO 42: no such luck 
MACRO_DEFINER(BAR) // hoping for #define BAR 42: likewise 

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

हमेशा कोड जनरेशन होता है: निर्माण समय पर सी या सी ++ उत्पन्न करना। फिर यदि आप अपनी पीढ़ी प्रणाली को ट्विक करते हैं तो आप जिस भी पाठ प्रतिस्थापन या विस्तार का सपना देख सकते हैं, वह संभव है।

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