2012-01-23 15 views
7

मेरी कोड के कुछ हिस्सों में एक पूर्वप्रक्रमक प्रतीक के मूल्य पर निर्भर करते हैं:वहाँ सी में एक पूर्वप्रक्रमक प्रतीक मान का प्रकार की जाँच करने के तरीका है/C++

int a() 
{ 
#if SDK_VERSION >= 3 
    return 1; 
#else 
    return 2; 
#endif 
} 

तुलना SDK_VERSION के मूल्य का निर्भर करता है। यह एक पूर्णांक या कुछ ऐसा होने की उम्मीद है जो इस मामले में, पूर्णांक से तुलना करता है। 3. यदि SDK_VERSION ऐसा कुछ है जिसे पूर्णांक से तुलना नहीं किया जा सकता है, तो संकलन त्रुटि होगी।

यदि SDK_VERSION अपेक्षित प्रकार का नहीं है तो संकलन को रद्द करने का कोई तरीका है? उदाहरण के लिए:

#if type(SDK_VERSION) != int # Does not compile, I know 
#error "SDK_VERSION must be an integer." 
#endif 
+1

त्रुटि संदेश थोड़ा और अस्पष्ट होगा, लेकिन 'एसडीके' सहित शीर्षलेख में 'int ___SDK_VERSION_SHOULD_BE_CONVERTIBLE_TO_INT___ = SDK_VERSION;' जैसे कुछ डालने से आपकी समस्या हल हो सकती है। –

+3

आप कहते हैं कि यदि आप 'SDK_VERSION' गलत प्रकार का है, तो क्या आप पहले से संकलन त्रुटि प्राप्त करते हैं, क्या आप एक अच्छा/अलग त्रुटि संदेश चाहते हैं? – spatz

+0

@ FrédéricHamidi: अपने पहचानकर्ताओं में डबल अंडरस्कोर से जुड़ी समस्याओं को अनदेखा करना। –

उत्तर

11

टेम्पलेट का उपयोग करें जैसे कि त्रुटि उत्पन्न करने के लिए:

template<typename T> struct macro_error; 

template<> struct macro_error<int> {}; 

template<typename T> void check(T) 
{ 
    macro_error<T> SDK_VERSION_must_be_int; 
} 
int ignored = (check(SDK_VERSION), 0); 

इस कोड संकलन त्रुटि उत्पन्न होगा, उस में निम्न स्ट्रिंग होने, अगर SDK_VERSION int नहीं है:

SDK_VERSION_must_be_int 

इन डेमो देखें:

और यह भी पहले मामले में त्रुटि संदेश पर ध्यान दें। यह प्रिंट करता है:

prog.cpp:9: error: ‘SDK_VERSION_must_be_int’ has incomplete type 
prog.cpp:9: warning: unused variable ‘SDK_VERSION_must_be_int’ 
+1

सी पर लागू नहीं है –

2

यह संकलन नहीं करता है, तो SDK_VERSION एक स्ट्रिंग है (लेकिन यह एक float ... के लिए काम करेगा):

int get_SDK_Version() 
{ 
    return SDK_VERSION; 
} 
4

नहीं। इसका कारण यह है कि प्रीप्रोसेसर प्रतीक का कोई प्रकार नहीं है।

प्रीप्रोसेसर प्रतीकों को सबसे अच्छी तरह से एक स्ट्रिंग से अधिक कठिन माना जाता है। सी का प्रकार प्रणाली वास्तव में संकलन चरण तक अस्तित्व में नहीं है, जो प्रीप्रोसेसर के जाने के बाद होता है।

+0

ओह, हालांकि मुझे जेसन का जवाब पसंद है - चालाक , लेकिन कुछ दस्तावेज जोड़ना सुनिश्चित करें, क्योंकि संकलन विफल होने पर, यह स्पष्ट नहीं है कि स्निपेट का इरादा SDK_VERSION के प्रकार की जांच करना था। – Matt

0

प्रीप्रोसेसर के पास प्रकार या भाषा की कोई भी कीवर्ड नहीं है।

0

मुझे लगता है कि आप यहां कुछ टेम्पलेट मेटा प्रोग्रामिंग खींच सकते हैं।

मैं अपने स्वयं के कुछ जादू का प्रयास करूंगा और अगर मुझे कुछ काम मिल रहा है तो एक उदाहरण पोस्ट करें। मेरा सिद्धांत यह है कि आप कक्षा या फ़ंक्शन टेम्पलेट को तुरंत चालू कर सकते हैं। टेम्पलेट की डिफ़ॉल्ट परिभाषा के परिणामस्वरूप संकलन त्रुटि होगी यदि यह उचित प्रकार का नहीं है। int के लिए एक टेम्पलेट विशेषज्ञता के परिणामस्वरूप कोई त्रुटि नहीं होगी।

यह टेम्पलेट और प्रीप्रोसेसर जादू के साथ अपने अनुभव की सीमा से बाहर है, लेकिन इसमें एक लायक है। एक मुद्दा मुझे उम्मीद है कि SDK_VERSION प्रतिस्थापित होने के प्रतीक से वास्तव में कुछ भी नहीं है। SDK_VERSION में कोई प्रकार नहीं है, प्रति-से।

सबसे अच्छा, मुझे लगता है कि आप यह जांच सकते हैं कि यह किस प्रकार परिवर्तित हो सकता है, लेकिन "निरंतर" परिभाषित प्रीप्रोसेसर की अवधारणा बहुत ही है ... ब्रूट फोर्स, लगभग हैकिश। यह एक आम प्रथा हो सकती है, लेकिन यह बिल्कुल सुरक्षित नहीं है। यह याद रखना सबसे अच्छा है कि वे खोज-और-प्रतिस्थापन के केवल एक प्रीप्रोसेसर संस्करण हैं।

0

वास्तव में, #if निर्देशक पूर्णांक के रूप में अपने अधिकार के बारे में सोचता है।

तो यदि आप जो चाहते हैं उसे हासिल करना चाहते हैं, तो आपको कुछ अंकगणित करना होगा।

gcc -c -o /dev/null test.c 

साथ

#define VERSION 7 

#if VERSION 
    #if VERSION - (VERSION % 10) 
    #warning Number out of range (1-9) 
    #else 
    #warning Number in range (1-9) 
    #endif 
#else 
    #warning Zero or not a number 
#endif 

संकलित आप संदेश प्राप्त होगा: उदाहरण के लिए: के साथ एक test.c फ़ाइल करना अगर आपके संस्करण 0 "नहीं एक नंबर के शून्य" ..., या एक पूर्णांक के रूप में (प्रीप्रोसेसर-वार) का मूल्यांकन नहीं करता है।

और यदि संस्करण पूर्णांक के रूप में evalutates, तो आप इसके मूल्य के अनुसार पहला या दूसरा संदेश प्राप्त करेंगे।

यह आपको वह करने की अनुमति देगा जो आप खोज रहे थे। #if पर

प्रलेखन: 123 या 0xCC या कुछ भी है कि एक पूर्णांक पुनरावर्ती मैक्रो विस्तार के बाद निरंतर का मूल्यांकन: http://gcc.gnu.org/onlinedocs/cpp/If.html

ध्यान दें कि पूर्णांक की तरह व्यक्त किया जा सकता।

यदि संख्या एक फ़्लोटिंग पॉइंट है: 3.14 इसे शून्य के रूप में माना जाता है।

आप केवल पूर्णांक नहीं होने वाले 0 (पूर्णांक) को अंतर नहीं कर सकते हैं। मैक्रो स्ट्रिंग कॉन्सटेनेशन का उपयोग करते हुए शायद एक संभावना है, लेकिन यह खोजना बाकी है।

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