2010-01-18 22 views
6

मैं पता है कि विपक्ष को इस तरह से पूर्वप्रक्रमक का उपयोग कर रहे हैं चाहते हैं:फ़ंक्शन कॉल को परिभाषित करने के लिए प्रीप्रोसेसर का उपयोग करने का नकारात्मक पक्ष क्या है?

#define SOME_FUNCTION someFunction(someArgument) 

मूल रूप से मैं इस तरह लग रहा है गलत (या निश्चित रूप से एक सबसे अच्छा अभ्यास नहीं) है - लेकिन मुझे यकीन है कि क्यों नहीं कर रहा हूँ ... मेरे प्रीप्रोसेसर कौशल सबसे अच्छे हैं।

उत्तर

0

यह कभी-कभी अधिक पठनीय फैशन में प्रक्रिया चरणों को परिभाषित करने के लिए एक बहुत बंद डोमेन में उपयोगी है:

void myfunc() { 
    DO_STEP_ONE; 
    THEN_ANOTHER_STEP; 
    KEEP_GOING; 
    LAST_STEP; 
} 

लेकिन आमतौर पर यह सिर्फ कोड कठिन पढ़ने और समझने में आसान बनाता है।

जब तक आपके कोड के पाठकों को यह पता नहीं चलता कि यह # परिभाषित करने का मतलब क्या है, और यह किसी प्रकार का छोटा कट है, तो आप लोगों को कोड की एक पंक्ति को समझने के लिए बस दो स्थानों पर देखने के लिए मिल रहे हैं (शीर्ष फ़ाइल और फ़ंक्शन में) एक के बजाए।

मैं इस तरह के दृष्टिकोण का बहुत ही कम उपयोग करता हूं।

+0

मैक्रोज़ का उपयोग करके उसी नाम के साथ फ़ंक्शंस का उपयोग करने से कहीं अधिक पठनीय नहीं है – user463035818

0

कि भाषा, संकलक, आदि, आदि, आदि पर निर्भर करेगा ...

हालांकि, इसके साथ कुछ भी गलत नहीं है, एक बार के रूप में नाम उन निर्देशों पहले से संकलन की प्रक्रिया होती है निकलता है।

पूर्व प्रोसेसर किसी अन्य के द्वारा हल किया जा सकता कंप्यूटर विज्ञान में अपनी वास्तविक मूल्य से सभी निरंतर संदर्भ, उचित कोड के साथ सभी छद्म समारोह, और इतने पर ...

0

सभी समस्याओं को दूर करता अविवेक के स्तर

यह इन अतिरिक्त अविवेक स्तरों :-)

में से एक है कि कुछ बिंदु पर है कि समारोह एक और तर्क की जरूरत है या आप की जरूरत नहीं है कहो इसे कॉल करने के लिए, आप उन सभी स्थानों को बदलने के बजाय #define बदल सकते हैं जहां फ़ंक्शन कहा जा रहा है।

उत्पादन कोड में रखने के लिए विकासशील, लेकिन खतरनाक के लिए उपयोगी ... मैं परिपक्व कोड होने के बाद उस नियम को प्रतिस्थापित करने के लिए प्रीप्रोसेसर चलाता हूं और जानता हूं कि मुझे इसे बदलने की आवश्यकता नहीं होगी।

+0

संकेत के बहुत से स्तर होने के बारे में क्या? ;) – daotoad

5

एक नकारात्मक पक्ष? आम तौर पर एक मैक्रो परिभाषा निष्पादन योग्य प्रतीक तालिका में समाप्त नहीं होती है। डीबग करने के लिए थोड़ा और मुश्किल है।

5
समस्या

कि तर्क जब भी उपयोग किया जाता है का मूल्यांकन फिर से कर रहे हैं = है:

#define MIN(A,B) ((A) < (B))?(A):(B); 

सूचना मैं '(' ')' बनाने के लिए सभी तर्कों रैप करने के लिए है कि यकीन है कि अभिव्यक्ति corectly का मूल्यांकन करता है । लेकिन अगर हम ऐसा करते हैं तो क्या होता है?

int s = MIN(++current,Max); 

यह कोडिंग मैं फ़ंक्शन कहने से पहले एक बार बढ़ने की अपेक्षा करता हूं।लेकिन क्योंकि यह एक मैक्रो यह परीक्षण में एक बार वृद्धि की है और दूसरी बार है अगर यह अभी भी अधिकतम

से छोटी है
+0

हालांकि यह वास्तव में मैक्रोज़ का नुकसान है, 'gcc' * कंपाइलर-विशिष्ट * एक्सटेंशन प्रदान करता है ताकि यह कार्य करने के लिए: '# परिभाषित करें MIN (ए, बी) ({टाइपोफ (ए) _ ए = (ए); टाइपऑफ (बी) _ बी = (बी); _ ए <_ बी? _ए: _ बी;}) '। – kennytm

+0

@ केनी: आपका मैक्रो फू मेरा से बेहतर है। मैने इसे आजमाया और इसने कार्य किया। हालांकि ऐसा नहीं लगता था, मुझे नहीं लगता था कि एक बयान (ब्लॉक) एक राजस्व के रूप में कार्य कर सकता है। –

+0

@ केनी: दुर्भाग्यवश, जीसीसी का विस्तार तब भी काम नहीं करेगा जब 'MIN' को वेरिएबल्स पर बुलाया गया था जिन्हें असाधारण रूप से' _a' और '_b' नाम दिया गया था। – jamesdlin

2

वहाँ कई समस्याओं के बारे में सोच सकते हैं:

  • C++ में मैक्रो कोई नाम स्थान है और वर्ग के दायरे, तो यह हर जगह एक ही है। इसके लिए एक उदाहरण दुर्भाग्यपूर्ण न्यूनतम और अधिकतम windows.h में कहीं परिभाषित करता है। यदि आप विंडोज़ के लिए प्रोग्रामिंग कर रहे हैं और windows.h शामिल हैं और std :: numeric_limits :: max() लिखना चाहते हैं तो अधिकतम कुछ कोड द्वारा प्रतिस्थापित किया जाएगा ... यह प्रीप्रोसेसर चलाने के बाद असम्बद्ध कोड छोड़ देता है। (ठीक है windows.h में न्यूनतम/अधिकतम मैक्रोज़ को बंद करने के तरीके हैं लेकिन यह अभी भी खराब डिज़ाइन है!)
  • मैक्रो को अच्छी तरह से डीबग नहीं किया जा सकता है। डीबगर लाइन पर रुक जाएगा मैक्रो का उपयोग मैक्रो के अंदर कोड पर नहीं किया जाता है ...
  • मैक्रो पैरामीटर का संभावित पुनर्मूल्यांकन (आप इसे मैक्रो के अंदर स्थानीय चर के साथ ब्लॉक करके रोक सकते हैं लेकिन यह डिबगिंग करेगा इससे भी बदतर!)
0

विशिष्ट प्रीप्रोसेसर कोड का उपयोग करने में आप नुकसान क्यों देखेंगे? सशर्त संकलन (गार्ड सहित शामिल) के अलावा किसी अन्य चीज़ के लिए प्रीप्रोसेसर मैक्रोज़ का उपयोग करना स्वचालित रूप से खराब माना जाना चाहिए। पूछने का सही सवाल यह है कि क्या किसी विशेष उपयोग के फायदे हैं।

प्रीप्रोसेसर मैक्रोज़ किसी भी तरह से दायरे या उपयोग का सम्मान नहीं करते हैं। वे अप्रत्याशित और कठिन-से-खोजने के तरीके में पूरी तरह से अच्छे कोड को पेंच कर सकते हैं। हमेशा उनसे बचें जब तक कि आपके पास एक का उपयोग करने का कोई अच्छा कारण न हो।

1

खैर अगर आपको लगता है कि क्या करना चाहिए (और वहाँ कुछ अवसरों जब आप हो सकता है कर रहे हैं), तो आप कम से कम मैक्रो के रूप में "समारोह की तरह" इस प्रकार परिभाषित करना चाहिए:

#define SOME_FUNCTION() someFunction(defaultArgument) 

अन्यथा आप लिखेंगे कोड है कि एक असाइनमेंट की तरह एक स्थिरता की तरह लग रहा था जब यह वास्तव में एक समारोह कॉल था; अर्थात;

x = SOME_FUNCTION ; // hidden function call 

लेकिन एक "समारोह की तरह" मैक्रो आप लिखने के लिए बाध्य नहीं किया जाएगा साथ:

x = SOME_FUNCTION() ; // shorthand function-call with default argument 

कौन सा बेहतर मैचों भाषा वाक्य रचना के साथ पूर्व प्रोसेसर वाक्य रचना।

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

0

नकारात्मकता यह है कि आप कोड छुपा रहे हैं। उल्टा यह है कि आप कोड छुपा रहे हैं।

नकारात्मक पक्ष आमतौर पर ऊपर की ओर बढ़ता है।

आम तौर पर इस विशेष दृष्टिकोण काफी बेकार है और जब तक कॉल अधिक की तरह

someModule-> someStorage-> functionList [storage.getFunctionName] .pointer-> SomeFunction (... समान रूप से अस्पष्ट तर्क लग रहा है ...),

ऐसा करने का कोई मतलब नहीं है। अगर केवल तर्क एक अस्पष्ट कॉल है, तो केवल तर्क का श्रेय। यदि यह केवल फ़ंक्शन है, तो केवल फ़ंक्शन को कम करें।दोनों हैं, तो आप

SOME_FUNCTION(SOME_ARGUMENT); 

के साथ बंद बेहतर हो सकता है समारोह और कुछ के साथ कहा जाता है कभी नहीं है, तो आप तर्क सूची से निकालकर और समारोह शरीर के अंदर प्राप्त करने की सोच सकते हैं। और यदि जोड़ी बहुत बार बदलती है, छोटे बदलावों में, आप रैपर कार्यों पर विचार कर सकते हैं।

मैक्रो के कोड में कई बग बनाने के बाद, आप उन्हें डीबग करने के लिए दर्द महसूस करेंगे और आप उन्हें बेकार तरीके से उपयोग नहीं करेंगे।

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

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