2013-09-25 5 views
11

क्या कोई प्री प्रीप्रोसेसर मैक्रो लिखने का कोई तरीका है जो विभिन्न तर्कों के आधार पर फैलता है कि यह किस तर्क को प्राप्त करता है?क्या सी मैक्रो के अंदर प्रीप्रोसेसर सशर्त डालना संभव है?

#define foo() ??? 

/* 1 */ 
foo(name) 

/* 2 */ 
foo(_) 

वांछित परिणाम:

/* 1 */ 
int name; 

/* 2 */ 
/*ignore*/ 

हाँ, मैं जानता हूँ कि मैक्रो बुराई कर रहे हैं। मैं इसे ज्यादातर जिज्ञासा से पूछ रहा हूं।

+12

मैक्रोज़ भयानक हैं। –

+2

क्या आप इस उद्देश्य को समझा सकते हैं, या शायद एक बेहतर उदाहरण दे सकते हैं? पैरामीटर को संकलन समय पर तय करना होगा, जिसका अर्थ है कि आप दो अलग-अलग मैक्रो नामों का भी उपयोग कर सकते हैं। – lurker

+0

@mbratch: इस विशेष मामले में, मैं चर के एक सेट को परिभाषित करने के लिए एक मैक्रो का उपयोग कर रहा हूं लेकिन कुछ चर वैकल्पिक हैं और मैं उन्हें परिभाषित करने से बचना चाहता हूं। एकाधिक मैक्रो नाम एक संयोजन विस्फोट के कारण अच्छी तरह से काम नहीं करेंगे: दो परिवर्तनीय नामों के साथ मुझे 'foo (a, b) ',' foo (a, _)', 'foo (_, b) ',' foo (_, b) 'और' के लिए अलग मैक्रोज़ की आवश्यकता होगी। foo (_, _) '। – hugomg

उत्तर

8

शायद कुछ मल्टी-स्टेज मैक्रो विस्तार का प्रयास करें? यह Boost preprocessor/control/if library द्वारा उपयोग की जाने वाली रणनीति है।

#define FOO_NAME 1 
#define FOO__ 2 

#define CONC(a,b) a##_##b 
#define FOO(x) CONC(FOO,x) 

मुझे नहीं लगता कि सी मैक्रो विस्तार के भीतर स्थितियों की जांच करने का कोई तरीका है।

सबसे अच्छी बात यह है कि मैं # स्ट्रिंगिंग ऑपरेटर का उपयोग करके स्ट्रिंग शाब्दिक में मैक्रो तर्कों को गुप्त करना और फिर रन-टाइम फ़ंक्शंस का उपयोग करके जांच करना चाहता हूं। (यह, हालांकि, अपने मामले के लिए काम करेंगे नहीं जहां उत्पादन चर घोषणाओं करना चाहते हैं।)

उदाहरण के लिए, निम्नलिखित प्रिंट "011":

#define FOO(x) (strcmp("NAME", #x) ? 1 : 0) 

main() 
{ 
    printf("%d", FOO(NAME)); 
    printf("%d", FOO(1)); 
    printf("%d", FOO(2)); 
} 

संकलक संभावना strcmp तुलना अनुकूलन होगा संकलन समय पर, यह वास्तविक प्री-प्रोसेसर सशर्त उपलब्ध होने के मुकाबले अब और अधिक अक्षम नहीं होगा। हालांकि, FOO बनाना एक सामान्य कार्य स्पष्ट और संभवतः उतना ही कुशल होगा।

+0

दिलचस्प चाल! लेकिन क्या ऐसा कोई तरीका है जहां मुझे "1" मामले के लिए सभी संभावनाओं को गिनने की आवश्यकता नहीं है? उदाहरण के लिए, यदि इसका '_' तो मैक्रो उपज 2 अगर यह कुछ और है तो यह 1 उत्पन्न करता है? – hugomg

+0

मैंने अपने उत्तर को सीमित वर्कअराउंड के साथ अपडेट किया जो आपके मूल प्रश्न के लिए काम नहीं करेगा। –

+0

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

8

गेविन स्मिथ के जवाब पर विस्तार करने के लिए, आप वास्तव में स्थिति एक मैक्रो विस्तार के भीतर जांच कर सकते हैं:

#define FOO_name 1 
#define FOO__ 0 

#define CONC(a,b) a##_##b 

#define IF(c, t, e) CONC(IF, c)(t, e) 
#define IF_0(t, e) e 
#define IF_1(t, e) t 

#define FOO(x) IF(CONC(FOO,x), int x;,) 

FOO(name) // -> int name; 
FOO(_) // -> /*nothing*/ 

आप रोमांच महसूस कर रहे हैं तो आप आसानी से IF का विस्तार, अल्पविराम अनुमति देने के लिए कर सकते हैं मैक्रो विस्तार, आदि के साथ दबाने सहायक मैक्रोज़।

उपरोक्त के रूप में यह आवश्यक है कि आप पहले से सभी वांछित नामों को जानते हों।

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