2012-04-19 10 views
6

मैं इस तरह कुछ करने के लिए करना चाहते हैं:क्या मैक्रो के लिए कई तर्कों का मूल्यांकन करना संभव है?

#define NEED3ARGS(a1,a2,a3) ("[" #a1 " + " #a2 " + " #a3 "]") 
#define MULTIARG() ARG1, ARG2, ARG3 

NEED3ARGS(MULTIARG()) 

और मुझे यह पसंद उत्पादन कुछ करने की उम्मीद:

("[" "ARG1" " + " "ARG2" " + " "ARG3" "]") 

लेकिन बजाय मेरे पास है:

$ cpp multiarg.c 
# 1 "multiarg.c" 
# 1 "<built-in>" 
# 1 "<command-line>" 
# 1 "multiarg.c" 

multiarg.c:4:23: error: macro "NEED3ARGS" requires 3 arguments, but only 1 given 
NEED3ARGS 

वहाँ एक है एएनएसआई-सी/जीएनयू जीसीसी और सी प्रीप्रोसेसर का उपयोग करने के लिए मैं क्या करना चाहता हूं?

धन्यवाद!

उत्तर

12

आपको कुछ संकेत की आवश्यकता है। C99 के साथ:

#define NEED3ARGS(a1,a2,a3) ("[" #a1 " + " #a2 " + " #a3 "]") 
#define INVOKE_NEED3ARGS(...) NEED3ARGS(__VA_ARGS__) 
#define MULTIARG() ARG1, ARG2, ARG3 

INVOKE_NEED3ARGS(MULTIARG()) 

(। C99 सख्ती से की आवश्यकता नहीं है, आप एक निश्चित arity मैक्रो के साथ variadic मैक्रो जगह ले सकता है)

आप विज़ुअल सी का उपयोग कर अपने स्रोत संकलित करने के लिए की जरूरत है ++ लिए, आप

#define NEED3ARGS(a1,a2,a3) ("[" #a1 " + " #a2 " + " #a3 "]") 
#define INVOKE_NEED3ARGS_(...) NEED3ARGS __VA_ARGS__ 
#define INVOKE_NEED3ARGS(...) INVOKE_NEED3ARGS_((__VA_ARGS__)) 
#define MULTIARG() ARG1, ARG2, ARG3 

INVOKE_NEED3ARGS(MULTIARG()) 

क्यों अविवेक की जरूरत है के लिए के रूप में: और भी अधिक अविवेक (a compiler bug की वजह से) की जरूरत है एक मैक्रो तर्क evalu नहीं है एटेड और मैक्रो-प्रतिस्थापित होने तक इसे प्रतिस्थापन सूची में प्रतिस्थापित किया जाता है। इसलिए, जब आप , MULTIARG() को तक मैक्रो आमंत्रण के बाद मूल्यांकन नहीं किया जाएगा, तो इसे एक तर्क के रूप में माना जाता है।

INVOKE_NEED3ARGS मैक्रो यह सुनिश्चित करता है कि NEED3ARGS से पहले इसके तर्कों का पूरी तरह से मूल्यांकन किया जाता है। __VA_ARGS__ मैक्रो-प्रतिस्थापित तर्कों द्वारा INVOKE_NEED3ARGS पर प्रतिस्थापित किया गया है, जो ARG1, ARG2, ARG3 है, तो NEED3ARGS उन तर्कों के साथ लागू किया गया है।

6

हाँ,

#define NEED3ARGS(a1,a2,a3) ("[" #a1 " + " #a2 " + " #a3 "]") 
#define MULTIARG() ARG1, ARG2, ARG3 
#define NEED1ARG(ARG) NEED3ARGS(ARG) 

NEED1ARG(MULTIARG()) 

आप किसी अन्य मैक्रो कॉल में लपेट के लिए तो इससे पहले कि NEED3ARGS कहा जाता है तर्क का विस्तार हो जाता है की जरूरत है।

1

जेम्स मैकनेलिस के जवाब में जोड़ना, यदि आपको इस कार्य को कई फ़ंक्शन-जैसे मैक्रोज़ (FLM) पर लागू करने की आवश्यकता है, तो आप अपने लिए चाल करने के लिए एक "Invoke" मैक्रो परिभाषित कर सकते हैं। यहां एक पूर्ण कार्य उदाहरण है:

#include<cstdio> 
int f(int x,int y) { return x + y; } 
#define g(x,y) x+y 
#define XY 1,2 
#define _g(arg) g(arg) 
#define invoke(flm,...) flm(__VA_ARGS__) 
int main(int argc, char ** argv) 
{ 
    printf("%d\n",f(XY));  // functions are easy 
    printf("%d\n",_g(XY));  // Jam,es' way 
    printf("%d\n",invoke(g,XY)); // with generic invoke flm 
    return 0; 
} 
संबंधित मुद्दे

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