2012-11-05 10 views
6

मैं एक microcontroller के लिए एम्बेडेड सी कोड लिख रहा हूँ। कोड को तीन अलग सर्किट बोर्डों के बीच साझा किया जाना है, और इनपुट/आउटपुट कॉन्फ़िगरेशन प्रारंभिकरण के दौरान कुछ तालिकाओं से रन टाइम पर सेट होते हैं।संकलन समय के दौरान वैध इनपुट के लिए मैं सी फ़ंक्शन कैसे देखूं?

माइक्रोकंट्रोलर में 24 एडीसी चैनल हैं, और मेरे पास एक ऐसा फ़ंक्शन है जो एक पिन को एडीसी चैनल के रूप में सेट या साफ़ कर सकता है। इसका मतलब है कि फ़ंक्शन में इनपुट 0 से 23 (जो तालिका में सेट है) हो सकता है और कुछ भी नहीं।

मैं किसी प्रकार का प्रीप्रोसेसर या कंपाइलर "चीज" रखना चाहता हूं जो यह पहचान सकता है कि फ़ंक्शन को 0-23 के अलावा कोई मान प्राप्त हुआ है और किसी प्रकार की त्रुटि या चेतावनी फेंक दी गई है और कोड को संकलित करने से रोकें तालिका में एक अवैध मूल्य।

क्या किसी को इस बारे में कुछ सलाह है कि यह कैसे करना है?

+1

आप स्थिर आवेषण का उपयोग कर सकते हैं। – imreal

+1

मुझे लगता है कि आप यहां चीजों को भ्रमित कर रहे हैं। एक फ़ंक्शन रनटाइम और प्रीप्रोसेसर या कंपाइलर के दौरान इनपुट प्राप्त करता है केवल संकलन के दौरान ज्ञात सामग्री की जांच कर सकता है। आपको अपने फ़ंक्शन की शुरुआत में एक चेक जोड़ना चाहिए जो इनपुट सीमाओं को सत्यापित करेगा। – SomeWittyUsername

+0

कारण यह है कि मैंने सोचा था कि संकलन के दौरान इसे जांचने का कोई तरीका हो सकता है कि कभी-कभी उस कार्य को पास किए गए किसी भी मूल्य को संकलित समय पर पहले से ज्ञात नहीं किया जाता है। – Adam

उत्तर

3

अधिकांश कंपाइलर्स (प्रीप्रोसेसरों) पर आप #error निर्देश का उपयोग कर सकते हैं।

आईई।

#define ADC_CHANNEL 34 
#if ADC_CHANNEL > 23 
#error ADC_CHANNEL exceeds maximum allowed value 
#endif 

उपरोक्त एक त्रुटि फेंक देगा, और संकलित नहीं होगा।

फिर अपने कार्य में इनपुट के रूप में ADC_CHANNEL का उपयोग करें।

या आप ADC_CHANNEL एक enum बनाने के लिए, और परिभाषित ADC_CHANNEL_0 = 0, ADC_CHANNEL_1 = 1 ... ADC_CHANNEL_23 = 23 कर सकते हैं। फिर अपने फ़ंक्शन को ADC_CHANNEL_t टाइप करें, या जो कुछ भी आप इसे कॉल करना चाहते हैं, और इस तरह यदि फ़ंक्शन को तर्कसंगत प्रकार का तर्क के रूप में कॉल किया जाता है, तो आउट-ऑफ-बाउंड मान का उपयोग करने का कोई तरीका नहीं होगा।

उदाहरण:

typedef enum {ADC_CHANNEL_0 = 0, 
       ADC_CHANNEL_1 = 1, 
       ADC_CHANNEL_2 = 2, 
       // ...etc... 
       ADC_CHANNEL_22 = 22, 
       ADC_CHANNEL_23 = 23} adc_channel_t; 

void setClearAdcPin(adc_channel_t adcChannel) { 
    // ...function body... 
} 

(आप तकनीकी रूप से = 0, = 1, आदि, के बाद से संकलक है कि आदेश से यह निष्कर्ष निकाल जाएगा की जरूरत नहीं है तक 0 पर डिफ़ॉल्ट enum आरंभ और 1 से वेतन वृद्धि के लिए। प्रत्येक मान। लेकिन प्रत्येक मान को मैन्युअल रूप से परिभाषित करना सुरक्षित है, और आपको केवल 3 संभावित एडीसी चैनलों को शामिल करने की सुविधा देता है, जिन्हें आप संभवतः उपयोग कर सकते हैं, भले ही वे लगातार न हों।)

+1

दुर्भाग्य से, मानक पूर्णांक स्वीकार किया जाएगा भले ही func en enum की अपेक्षा करता है: http://liveworkspace.org/code/69da85aa7cfefb69d7d6f23b940f7462 – SomeWittyUsername

+0

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

+0

टाइपिंग को त्रुटि को फेंकने के लिए कुछ कंपाइलर विकल्पों का उपयोग करें। –

1

आप कंपाइलर में रेंज की जांच कर सकते हैं (प्रीप्रोसेसर के विपरीत) इस गंदे चाल से:

const char PIN = 23; 
struct check_23 { 
    unsigned long bits: PIN+9; 
}; 

इस संकलन नहीं होगा यदि पिन> 23

फिर, अपने कार्य यह सुनिश्चित करना केवल संकलन समय दिया जाता है तर्कों के रूप स्थिरांक आप एक समारोह के बजाय एक मैक्रो की आपूर्ति:

#define CONCAT(a, b) a##b 
#define MAKESTRUCTNAME(a,b) CONCAT(a,b) 

#define PinFunction(PinArg)\ 
struct MAKESTRUCTNAME(PinCheckStruct, __LINE__) {\ 
    unsigned long bits: (PinArg)+9;\ 
};\ 
RealPinFunction(PinArg);\ 
+0

यह फ़ंक्शन कॉल से कैसे संबंधित है? – SomeWittyUsername

+0

@icepack, आप इसके साथ प्रत्येक फ़ंक्शन कॉल प्रीपेड करते हैं। (तब उसे वापस लिखने का समय नहीं था) –

+0

अच्छा। दुरुपयोग को रोकने के लिए आपको उपयोगकर्ता को वास्तविक फ़ंक्शन इंटरफ़ेस से इनकार करने की भी आवश्यकता होगी। इसके अलावा सी ++ टेम्पलेट क्षमताओं में से कुछ को अनुकरण करने के वीर प्रयास की तरह लगता है :) – SomeWittyUsername

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