2011-10-17 17 views
9

से पहले प्रीप्रोसेसर टोकन का मूल्यांकन करें मैं किसी और चीज़ के साथ संयोजित होने से पहले टोकन का मूल्यांकन करना चाहता हूं। "समस्या" है कि मानक एक तर्क से प्रतिस्थापन सूची में एक ## preprocessing टोकन के प्रत्येक उदाहरण## concatenation

के रूप में व्यवहार निर्दिष्ट करता है इससे पहले कि प्रतिस्थापन सूची के लिए और अधिक मैक्रो नाम के लिए पुनर्परीक्षण होते है की जगह, (नहीं है) हटा दिया गया है और पूर्व preprocessing टोकन निम्नलिखित preprocessing टोकन के साथ concatenated है।

निम्न उदाहरण में

इसलिए,

#include <stdlib.h> 

struct xy { 
    int x; 
    int y; 
}; 

struct something { 
    char * s; 
    void *ptr; 
    int size; 
    struct xy *xys; 
}; 
#define ARRAY_SIZE(a) (sizeof(a)/sizeof((a)[0])) 

#define DECLARE_XY_BEGIN(prefix) \ 
struct xy prefix ## _xy_table[] = { 

#define XY(x, y) {x, y}, 

#define DECLARE_XY_END(prefix) \ 
    {0, 0} \ 
}; \ 
struct something prefix ## _something = { \ 
    "", NULL, \ 
    ARRAY_SIZE(prefix ## _xy_table), \ 
    &(prefix ## _xy_table)[0], \ 
}; 

DECLARE_XY_BEGIN(linear1) 
    XY(0, 0) 
    XY(1, 1) 
    XY(2, 2) 
    XY(3, 3) 
DECLARE_XY_END(linear1) 


#define DECLARE_XY_BEGIN_V2() \ 
struct xy MYPREFIX ## _xy_table[] = { 

#define DECLARE_XY_END_V2() \ 
    {0, 0} \ 
}; \ 
struct something MYPREFIX ## _something = { \ 
    "", NULL, \ 
    ARRAY_SIZE(MYPREFIX ## _xy_table), \ 
    &(MYPREFIX ## _xy_table)[0], \ 
}; 

#define MYPREFIX linear2 
DECLARE_XY_BEGIN_V2() 
    XY(0, 0) 
    XY(2, 1) 
    XY(4, 2) 
    XY(6, 3) 
DECLARE_XY_END_V2() 
#undef MYPREFIX 

पिछले घोषणा

struct xy MYPREFIX_xy_table[] = { 
{0, 0}, 
{2, 1}, 
{4, 2}, 
{6, 3}, 
{0, 0} }; struct something MYPREFIX_something = { "", 0, (sizeof(MYPREFIX_xy_table)/sizeof((MYPREFIX_xy_table)[0])), &(MYPREFIX_xy_table)[0], }; 

में विस्तार किया जाता है और

struct xy linear2_xy_table[] = { 
{0, 0}, 
{2, 1}, 
{4, 2}, 
{6, 3}, 
{0, 0} }; struct something linear2_something = { "", 0, (sizeof(linear2_xy_table)/sizeof((linear2_xy_table)[0])), &(linear2_xy_table)[0], }; 

नहीं है कि मैं चाहता हूँ। क्या मैक्रोज़ को परिभाषित करने का कोई तरीका है जो इसे उत्पन्न करता है? मैक्रोज़ का पहला सेट करता है, लेकिन मैं उपसर्ग डुप्लिकेशंस से बचना चाहता हूं और केवल इसे एक बार परिभाषित करना चाहता हूं। तो क्या उपसर्ग को #define के साथ सेट करना संभव है और मैक्रोज़ इसका उपयोग करने दें?

+0

संभव डुप्लिकेट [कैसे सी पूर्वप्रक्रमक के साथ दो बार जोड़ और "आर्ग ## में के रूप में एक मैक्रो विस्तार करने के लिए \ _ # # मैक्रो "?] (Http://stackoverflow.com/questions/1489932/how-to-concatenate-twice-with-the-c-preprocessor-and-expand-a-macro-as-in-arg) कृपया कोशिश करें उदाहरणों को कम करने के लिए :-) –

उत्तर

4

आप इसके लिए दूसरे स्तर के विस्तार का उपयोग कर सकते हैं, उदाहरण के लिए।

#define XY_HLP1(a) DECLARE_XY_BEGIN(a) 
#define XY_HLP2(a) DECLARE_XY_END(a) 
#define DECLARE_XY_BEGIN_V2() XY_HLP1(MYPREFIX) 
#define DECLARE_XY_END_V2() XY_HLP2(MYPREFIX) 
+0

हाँ, मुझे यह पसंद है। पुराने मैक्रोज़ को बदलने और दूसरों के लिए संभावित विलय समस्याओं को बनाने की आवश्यकता नहीं है, और यहां तक ​​कि यदि डबल विस्तार को समझने के लिए सहजता से नहीं हो सकता है, तो यह भी स्पष्ट है कि वही उपसर्ग दोनों स्थानों का उपयोग किया जाता है। – hlovdal

11

You can use a macro for concatenation

#define CONCAT_(A, B) A ## B 
#define CONCAT(A, B) CONCAT_(A, B) 

की तरह इस तो काम करता है

#define A One 
#define B Two 
CONCAT(A, B) // Results in: OneTwo 
की
+1

मुझे कभी नहीं समझा कि ऐसी चीजों को दो स्तरों की आवश्यकता क्यों है। मैक्रो विस्तार के लिए पहला स्तर है, और दूसरा वास्तविक संयोजन के लिए दूसरा है? – ijustlovemath

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