2010-10-03 9 views
5

जीसीसी की शिकायत करता है, तो मुझे क्या करना इस:क्या मैं अंत में बदले में __VA_ARGS के साथ वैरिएडिक सी प्रीप्रोसेसर मैक्रोज़ परिभाषित कर सकता हूं?

#define M(obj,met, ..., contents) obj##_##met(const void * self, __VA_ARGS__) { \ 
    contents \ 
    } 

मुझे देते हुए इन 2 कारणों:

error: missing ')' in macro parameter list 
warning: __VA_ARGS__ can only appear in the expansion of a C99 variadic macro 

जाहिर है, C99 - शैली variadic मैक्रो अंडाकार के बाद समापन कोष्ठक तुरंत उम्मीद करते हैं, प्रभावी ढंग से कि variadic की मांग सूची मैक्रो के अंतिम तर्क हो। मुझे उपरोक्त मैक्रो में वर्णित मेरे शॉर्टेंड नोटेशन का उत्पादन करने के लिए बीच में रहने की आवश्यकता है। क्या जीसीसी इस सुविधा का समर्थन करता है, एक और (गैर-सी 99) वैरिएडिक मैक्रो शैली का उपयोग कर? क्या मैं इसे किसी और तरीके से अनुकरण कर सकता हूं? मैं अंत में विविधता सूची नहीं चाहता, यह मेरी धारणा को भ्रमित कर देगा। और मैं केवल जीसीसी का उपयोग कर सकता हूं।

+0

* मैं अंत में विविध सूची नहीं चाहता हूं, यह मेरी धारणा को भ्रमित कर देगा। और मैं केवल जीसीसी का उपयोग कर सकता हूं। * आप भाग्य से बाहर हैं। –

+0

[बूस्ट.प्रप्रोसेसर] (http://www.boost.org/doc/libs/1_43_0/libs/preprocessor/doc/index.html) देखें। मैं लगभग निश्चित हूं कि आप इसे कर सकते हैं बशर्ते आप एक अलग तर्क के रूप में 'सामग्री' की पहचान करने की कोशिश करना बंद कर दें - आप चरम तर्कों के अंतिम तर्क की पहचान करने के लिए प्रीप्रोसेसर सामग्री का एक हिस्सा उपयोग करते हैं। परिभाषा निश्चित रूप से थोड़ा अधिक जटिल है। –

उत्तर

7

नहीं आप नहीं कर सकते। ... अंत में दिखाई देना चाहिए।

लेकिन आप के रूप में

#define M(obj,met, ...) obj##_##met(const void * self, __VA_ARGS__) 

M को परिभाषित करने और के रूप में

void M(foo, bar, int x, char y, double z) { 
    content; 
} 
+0

:(जो मुझे डर था। धन्यवाद: डी –

5

इसका इस्तेमाल आप अंत में ... डाल करने के लिए है, लेकिन LAST और POP_LAST मैक्रो का उपयोग कर, आप एक ही रख सकते हैं सकता है अपने मैक्रो के लिए तर्कों का क्रम और इसे इस तरह परिभाषित करें:

#define M(obj,met, ...) obj##_##met(const void * self, POP_LAST(__VA_ARGS__)) { \ 
    LAST(__VA_ARGS__) \ 
    } 

यहाँ आपको इन मैक्रो कैसे परिभाषित कर सकते हैं:

/* This counts the number of args */ 
#define NARGS_SEQ(_1,_2,_3,_4,_5,_6,_7,_8,N,...) N 
#define NARGS(...) NARGS_SEQ(__VA_ARGS__, 8, 7, 6, 5, 4, 3, 2, 1) 

/* This will let macros expand before concating them */ 
#define PRIMITIVE_CAT(x, y) x ## y 
#define CAT(x, y) PRIMITIVE_CAT(x, y) 

/* This will pop the last argument off */ 
#define POP_LAST(...) CAT(POP_LAST_, NARGS(__VA_ARGS__))(__VA_ARGS__) 
#define POP_LAST_1(x1) 
#define POP_LAST_2(x1, x2) x1 
#define POP_LAST_3(x1, x2, x3) x1, x2 
#define POP_LAST_4(x1, x2, x3, x4) x1, x2, x3 
#define POP_LAST_5(x1, x2, x3, x4, x5) x1, x2, x3, x4 
#define POP_LAST_6(x1, x2, x3, x4, x5, x6) x1, x2, x3, x4, x5 
#define POP_LAST_7(x1, x2, x3, x4, x5, x6, x7) x1, x2, x3, x4, x5, x6 
#define POP_LAST_8(x1, x2, x3, x4, x5, x6, x7, x8) x1, x2, x3, x4, x5, x6, x7 

/* This will return the last argument */ 
#define LAST(...) CAT(LAST_, NARGS(__VA_ARGS__))(__VA_ARGS__) 
#define LAST_1(x1) x1 
#define LAST_2(x1, x2) x2 
#define LAST_3(x1, x2, x3) x3 
#define LAST_4(x1, x2, x3, x4) x4 
#define LAST_5(x1, x2, x3, x4, x5) x5 
#define LAST_6(x1, x2, x3, x4, x5, x6) x6 
#define LAST_7(x1, x2, x3, x4, x5, x6, x7) x7 
#define LAST_8(x1, x2, x3, x4, x5, x6, x7, x8) x8 

ये मैक्रो 8 तर्क के लिए काम करेंगे। यदि आप चाहें तो आप आसानी से उन्हें संभालने के लिए उन्हें बढ़ा सकते हैं।

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

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