2011-12-28 4 views
8

मेरे पास यह मैक्रो कोड है, जो मुझे सी enum और एक निर्माण का उपयोग करके तारों के रूप में गणना किए गए नामों की एक सूची को परिभाषित करने की अनुमति देता है। यह मुझे गणक नामों को डुप्लिकेट करने से रोकता है (और संभवतः बड़ी सूचियों के लिए त्रुटियों को पेश करता है)।गिनती प्रीप्रोसेसर मैक्रोज़

#define ENUM_DEFINITIONS(F) \ 
    F(0, Item1) \ 
    F(5, Item2) \ 
    F(15, Item3) \ 
    ... 
    F(63, ItemN) 

तो:

enum Items { 
    #define ITEM_ENUM_DEFINE(id, name) name = id, 
    ENUM_DEFINITIONS(ITEM_ENUM_DEFINE) 
    #undef ITEM_ENUM_DEFINE 

, जो जब विस्तार हुआ, चाहिए उत्पादन:

enum Items { 
    Item1 = 0, 
    Item2 = 5, 
    Item3 = 15, 
    ... 
    ItemN = 63, 
} 

कार्यान्वयन फ़ाइल में, मैं इस कोड है:

const char* itemNames[TOTAL_ITEMS]; 
int iter = 0; 

#define ITEM_STRING_DEFINE(id, name) itemNames[iter++] = #name; 
    ENUM_DEFINITIONS(ITEM_STRING_DEFINE) 
#undef ITEM_STRING_DEFINE 

जो, विस्तारित होने पर, उत्पादन:

itemNames[iter++] = "Item1"; 
itemNames[iter++] = "Item2"; 
itemNames[iter++] = "Item3"; 
... 
itemNames[iter++] = "ItemN"; 

मैं जानना चाहता हूं कि मैंने इस फैशन में कितने गणक आइटम बनाए हैं और इसे संकलन-समय सरणी में पास करने में सक्षम हैं। उपर्युक्त उदाहरण में, यह संकलन-समय पर TOTAL_ITEMS = N निर्धारित करेगा। क्या इस तरह मैक्रो इनोकेशन को गिनना संभव है?

मैं एक गैर मानक काउंटर मैक्रो, फ़ाइल और लाइन मैक्रो के लिए इसी तरह का उल्लेख देखा है, लेकिन मैं आशा करती हूं वहाँ एक और अधिक मानक तरीका है।

मैक्रोज़ का उपयोग किए बिना इसे प्राप्त करने का एक बेहतर तरीका सुनने में रुचि रखने में भी रुचि होगी।

+0

आपको 'enum' और तारों की सरणी दोनों की आवश्यकता क्यों है? – Philip

+0

ऐसा लगता है कि यह मेरी काम की रेखा में काफी बार आता है। एक उदाहरण एक राज्य मशीन होगी जहां राज्यों की गणना की जाती है, और फ्रंट-एंड जीयूआई वर्तमान स्थिति का नाम प्रदर्शित करता है। इसे केवल एक बार परिभाषित करना सुविधाजनक है, और यह उन अन्य डेवलपर्स के लिए आसान बनाता है जो नए राज्य जोड़ना चाहते हैं। – Eyal

उत्तर

7

निम्नलिखित काम करना चाहिए:

#define ITEM_STRING_DEFINE(id, name) #name, // note trailing comma 
const char *itemNames[] = { 
    ENUM_DEFINITIONS(ITEM_STRING_DEFINE) 
}; 

#define TOTAL_ITEMS (sizeof itemNames/sizeof itemNames[0]) 

संपादित: यह देखते हुए हम सूची में अनावश्यक अंतिम अल्पविराम बारे में चिंता करने की जरूरत नहीं है के लिए रेमंड चेन के लिए धन्यवाद। (मैं Is the last comma in C enum required? में सख्त सी 8 9 कंपाइलर्स के साथ enums के लिए समस्या का दुरुपयोग कर रहा था।)

+1

आपको पिछली कॉमा खाने की जरूरत नहीं है। एक पिछला कॉमा कानूनी है और अनदेखा है। –

+0

अंतिम अनावश्यक कॉमा के बारे में, मुझे याद है कि एसजीआई आईरिक्स कंपाइलर इसके बारे में एक गैर-दबाने वाली चेतावनी जारी करेगा, जिसने मुझे हमेशा इसे छोड़ने के लिए मजबूर किया। –

2

मैक्रोज़ का उपयोग किए बिना इसे प्राप्त करने का एक बेहतर तरीका सुनने में रुचि रखने में भी रुचि होगी।

आप हमेशा के लिए .c और .h फ़ाइलों को उत्पन्न करने के लिए रूबी या पायथन जैसे स्क्रिप्टिंग भाषा का उपयोग कर सकते हैं। यदि आप इसे अच्छी तरह से करते हैं, तो आप अपनी स्क्रिप्ट को अपने मेकफ़ाइल में एकीकृत कर सकते हैं।

+1

मैं आम तौर पर उन दृष्टिकोणों से नापसंद करता हूं जो निर्माण आवश्यकताओं के लिए एक और भाषा जोड़ते हैं। – Alex

1

मुझे पता है कि यह एक पूर्ण उत्तर नहीं है। आप इस तरह के आसपास एक मैक्रो बना सकते हैं।

#include <stdio.h> 

const char * array[] = { 
    "arr1", "arr2", "arr3", "arr4" 
}; 

int main (int argc, char **argv)$ 
{ 
    printf("%d\n", sizeof(array)/sizeof(const char *)); 
} 

आप अपने enum तो यह सतत तत्वों इस तरह आप sth कर सकते हैं है (बूस्ट से)

enum { A=0,B,C,D,E,F,N }; 
const char arr[N]; // can contain a character for each enum value 
4

संशोधित कर सकते हैं, तो आप आमंत्रण गिनती करने के लिए उसी तकनीक का उपयोग कर सकते हैं।

enum itemscounter { 
    #define ITEM_ENUM_DEFINE(id, name) name##counter, 
    ENUM_DEFINITIONS(ITEM_ENUM_DEFINE) 
    #undef ITEM_ENUM_DEFINE 
TOTAL_ITEMS 
}; 
+1

मैंने उपर्युक्त उत्तर स्वीकार कर लिया, लेकिन लगता है कि यह एक बहुत अच्छा (और चालाक) दृष्टिकोण भी है। धन्यवाद! – Eyal

0

सुझाव देखें म्यू डायनेमिक्स 'Enums, Strings and Laziness'; ये कम से कम आप जो भी कर रहे हैं उससे संबंधित हैं।

अन्यथा, Boost Preprocessor संग्रह (जो सी प्रीप्रोसेसर के साथ-साथ सी ++ प्रीप्रोसेसर के साथ प्रयोग योग्य है) को देखें।