2009-08-17 20 views
5

क्या सी/सी ++ मैक्रो "BUILD(a, i)" को परिभाषित करना संभव है जो "x[0], x[1], x[2], ..., x[i]" तक फैलता है?मैक्रो रिकर्सिव विस्तार एक अनुक्रम

#define BUILD(x, 0) x[0] 
#define BUILD(x, 1) x[0], x[1] 
#define BUILD(x, 2) x[0], x[1], x[2] 
... 

ऐसा लगता है कि BOOST_PP_ENUM_PARAMS नौकरी कर सकता है। मुझे लगता है कि मैं सिर्फ # शामिल कर सकता हूं, लेकिन मुझे यह जानने में दिलचस्पी है कि यह कैसे और क्यों काम करता है, कोई भी समझा सकता है?

मैं एक समारोह f(int, ...) जो एन पूर्णांक तर्क x[i], 0 < लेता कॉल करना चाहते हैं = मैं < एन कहाँ एन ceil(sizeof(A)/sizeof(B)) होने के लिए जाना जाता है। तो दुर्भाग्यवश, मैं varargs या टेम्पलेट्स का उपयोग नहीं कर सकता।

+0

संबंधित: http://stackoverflow.com/questions/824639/variadic-recursive-preprocessor-macros-is-it-possible/893684 –

+0

क्या समस्या क्या तुम सच में हल करने की कोशिश कर रहे हैं? अर्थात। इस मैक्रो का नतीजा क्या होगा? क्या टेम्पलेट समाधान (जहां रिकर्सन संभव है) की अनुमति देने के लिए उपयोग को थोड़ा सा बदला जा सकता है? –

+0

मेरा अंतिम संपादन देखें। –

उत्तर

14

यह संभव है, लेकिन आपको कुछ मैन्युअल काम करना है और ऊपरी सीमा है।

#define BUILD0(x) x[0] 
#define BUILD1(x) BUILD0(x), x[1] 
#define BUILD2(x) BUILD1(x), x[2] 
#define BUILD3(x) BUILD2(x), x[3] 
#define BUILD(x, i) BUILD##i(x) 

और ध्यान दें कि i एक पूर्णांक शाब्दिक, नहीं एक निरंतर परिकलित मान होना चाहिए।

बीटीडब्ल्यू, प्रीप्रोसेसर आमतौर पर जो भी सामान्य है उससे अधिक शक्तिशाली है, लेकिन उस शक्ति का उपयोग काफी मुश्किल है। बूस्ट एक पुस्तकालय प्रदान करता है जो पुनरावृत्ति समेत कुछ चीजों को आसान बनाता है। Boost Preprocessor Library देखें। ऐसी चीजों के लिए एक और पुस्तकालय है, लेकिन इस समय मेरा नाम मुझे बच निकला है।

संपादित करें: बूस्ट प्रीप्रोसेसर लाइब्रेरी एक समान तकनीक का उपयोग करती है। कुछ कोने के मामलों की समस्याओं को हल करने के लिए अतिरिक्त चाल के साथ, उच्च स्तरीय सुविधाओं के बीच कार्यान्वयन मैक्रोज़ साझा करें, कंपाइलर बग के आसपास काम करें, आदि ... सामान्य उद्देश्य लाइब्रेरी के संदर्भ में सामान्य सामान्य जटिलता जो सामान्य है लेकिन जो कभी-कभी आसान समझ को रोकती है कार्यान्वयन सिद्धांतों। शायद सबसे अधिक ध्यान देने योग्य चाल एक संकेत स्तर जोड़ना है ताकि यदि दूसरा पैरामीटर मैक्रो हो, तो इसका विस्तार किया जा सकता है। अर्थात।

साथ
#define BUILD_(x, i) BUILD##i(x) 
#define BUILD(x, i) BUILD_(x, i) 

एक कॉल

#define FOO 42 
BUILD(x, FOO) 

जो मैं क्या उजागर साथ संभव नहीं है कर सकते हैं।

+0

धन्यवाद, यह दिलचस्प है कि BUILD1..BUILD3 लगभग समान हैं ... क्या मेरे पास #define BUILD_ (x, j) BUILD_ (x, j-1), x [j] –

+0

जैसे कुछ नहीं हो सकता एक रोकथाम की स्थिति, और मैक्रोज़ बूट करने के लिए रिकर्सिव नहीं हो सकता है। एक अच्छा स्पष्टीकरण के लिए – Blindy

+0

+1! –

2

नहीं, यह नहीं है - मैक्रोज़ रिकर्सिव नहीं हो सकता है। और आपके द्वारा पोस्ट किए गए मैक्रोज़ भिन्न नहीं हैं, जिसका अर्थ है "पैरामीटर की विभिन्न संख्याएं"।

+1

धन्यवाद, मैंने विविधता टैग हटा दिया। –

0

ठीक है, मुझे एक ही समस्या थी, मेरा उद्देश्य मैक्रोज़ का उपयोग करके एन बाइट्स की सरणी के सभी मानों को मुद्रित करना था। मुझे लगता है कि आपको बहुत ही समस्या थी। यदि यह मामला था, तो इस समाधान को भविष्य की इसी तरह की समस्याओं का सामना करना चाहिए।

#define HEX_ARRAY_AS_STR(array, len) \ 
    ({ \ 
     int print_counter = 0; \ 
     print_buf = calloc(len*3+1, 1); \ 
     char *tmp_print_buf = print_buf; \ 
     uint8_t *array_flower = array; \ 
     while(print_counter++ < (len)){ \ 
      sprintf(tmp_print_buf, "%02X ", *(array_flower)++); \ 
      tmp_print_buf += 3; \ 
     } \ 
     print_buf; \ 
    }) 

#define eprintf(...) \ 
    do{ \ 
     char *print_buf; \ 
     printf(__VA_ARGS__); \ 
     if(print_buf) \ 
      free(print_buf); \ 
    }while(0) 

int 
main(int argc, char *argv[]) 
{ 
    uint8_t sample[] = {0,1,2,3,4,5,6,7}; 
    eprintf("%s\n", HEX_ARRAY_AS_STR(sample, 8)); 
    return 0; 
} 
+0

नहीं, यह वह नहीं है जो मैं करने की कोशिश कर रहा था। वैसे भी, यदि आप हमेशा HEX_ARRAY_AS_STR पर एक सरणी पास करते हैं तो आप आकार (सरणी)/sizeof (uint8_t) का उपयोग कर दूसरे पैरामीटर से छुटकारा पा सकते हैं –

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