इंडेंटिंग #defines


99

मुझे पता है कि #defineएस, आदि आमतौर पर कभी भी इंडेंट नहीं होते हैं। क्यों?

मैं इस समय कुछ कोड में काम कर रहा हूं जिसमें #defines, #ifdefs, #elses, #endifs आदि का भयानक मिश्रण है । इन सभी को अक्सर सामान्य कोड के साथ मिलाया जाता है। एस के गैर-इंडेंटिंग #defineउन्हें पढ़ने के लिए कठिन बनाता है। और गैर-इंडेंटेड #defineएस के साथ इंडेंटेड कोड का मिश्रण एक बुरा सपना है।

इंडेंट न करने का क्या फायदा #define? अगर मैं उन्हें इंडेंट करता हूं तो क्या यह मुझे बुरा इंसान बनाता है? क्या यह बहुत अच्छा नहीं है?

#ifdef SDCC
    #if DEBUGGING == 1
        #if defined (pic18f2480)
            #define FLASH_MEMORY_END 0x3DC0
        #elif defined (pic18f2580)
            #define FLASH_MEMORY_END 0x7DC0
        #else
            #error "Can't set  up flash memory end!"
        #endif
    #else
        #if defined (pic18f2480)
            #define FLASH_MEMORY_END 0x4000
        #elif defined (pic18f2580)
            #define FLASH_MEMORY_END 0x8000
        #else
            #error "Can't set  up flash memory end!"
        #endif
    #endif
#else
    #if DEBUGGING == 1
        #define FLASH_MEMORY_END 0x7DC0
    #else
        #define FLASH_MEMORY_END 0x8000
    #endif
#endif

जवाबों:


103

प्री-एएनएसआई सी प्रीप्रोसेसर ने एक लाइन की शुरुआत और "#" चरित्र के बीच स्थान की अनुमति नहीं दी; अग्रणी "#" को हमेशा पहले कॉलम में रखा गया था।

प्री-एएनएसआई सी कंपाइलर इन दिनों न के बराबर हैं। जो कभी शैली का उपयोग करें ("#" से पहले का स्थान या "#" और पहचानकर्ता के बीच का स्थान) जिसे आप पसंद करते हैं।

http://www.delorie.com/gnu/docs/gcc/cpp_48.html


26

जैसा कि कुछ पहले ही कह चुके हैं, कुछ प्री-एएनएसआई कंपाइलरों को लाइन पर पहले चार होने की आवश्यकता थी लेकिन उन्हें इसके साथ संलग्न होने के लिए डी प्रीप्रोसेसर निर्देश की आवश्यकता नहीं थी, इसलिए इंडेंटेशन इस तरह से किया गया था।

#ifdef SDCC
#  if DEBUGGING == 1
#    if defined (pic18f2480)
#      define FLASH_MEMORY_END 0x3DC0
#    elif defined (pic18f2580)
#      define FLASH_MEMORY_END 0x7DC0
#    else
#      error "Can't set  up flash memory end!"
#    endif
#  else
#    if defined (pic18f2480)
#      define FLASH_MEMORY_END 0x4000
#    elif defined (pic18f2580)
#      define FLASH_MEMORY_END 0x8000
#    else
#      error "Can't set  up flash memory end!"
#    endif
#  endif
#else
#  if DEBUGGING == 1
#    define FLASH_MEMORY_END 0x7DC0
#  else
#    define FLASH_MEMORY_END 0x8000
#  endif
#endif

मैंने अक्सर इस शैली को पुराने यूनिक्स हेडर में देखा है, लेकिन मैं इसे नफरत करता हूं क्योंकि वाक्यविन्यास रंग अक्सर ऐसे कोड पर विफल रहता है। मैं पूर्व-प्रोसेसर निर्देश के लिए एक बहुत ही दृश्यमान रंग का उपयोग करता हूं ताकि वे बाहर खड़े रहें (वे एक मेटा-स्तर पर हैं इसलिए कोड के सामान्य प्रवाह का हिस्सा नहीं होना चाहिए)। आप यह भी देख सकते हैं कि एसओ एक उपयोगी तरीके से अनुक्रम को रंग नहीं देता है।


16

प्रीप्रोसेसर निर्देशों के पार्सिंग के बारे में, C99 मानक (और इससे पहले C89 मानक) संकलक द्वारा तार्किक रूप से किए गए संचालन के अनुक्रम के बारे में स्पष्ट थे। विशेष रूप से, मेरा मानना ​​है कि इसका मतलब है कि यह कोड:

/* */ # /* */ include /* */ <stdio.h> /* */

के बराबर है:

#include <stdio.h>

बेहतर या बदतर के लिए, GCC 3.4.4 के साथ '-std = c89-upantic' किसी भी दर पर टिप्पणी-युक्त रेखा को स्वीकार करता है। मैं इस बात की वकालत नहीं कर रहा हूं कि एक शैली के रूप में - एक सेकंड के लिए नहीं (यह भयावह है)। मुझे लगता है कि यह संभव है।

ISO / IEC 9899: 1999 खंड 5.1.1.2 अनुवाद चरण कहता है:

  1. [चरित्र मानचित्रण, ट्रिग्राफ सहित]

  2. [लाइन splicing - backslash newline को हटाने]

  3. स्रोत फ़ाइल को व्हाइट-स्पेस वर्णों (टिप्पणियों सहित) के प्रीप्रोसेसिंग टोकन और अनुक्रम में विघटित किया गया है। स्रोत फ़ाइल आंशिक प्रीप्रोसेसिंग टोकन या आंशिक टिप्पणी में समाप्त नहीं होगी। प्रत्येक टिप्पणी को एक अंतरिक्ष चरित्र द्वारा प्रतिस्थापित किया जाता है। नए-लाइन वर्णों को बनाए रखा जाता है। नई-लाइन के अलावा श्वेत-अंतरिक्ष वर्णों के प्रत्येक गैर-रिक्त अनुक्रम को बरकरार रखा जाता है या एक स्थान वर्ण द्वारा प्रतिस्थापित किया जाता है, कार्यान्वयन-परिभाषित होता है।

  4. प्रीप्रोसेसिंग निर्देशों को निष्पादित किया जाता है, मैक्रो इनवोकेशन का विस्तार किया जाता है, [...]

धारा 6.10 प्रीप्रोसेसिंग निर्देश कहते हैं:

एक प्रीप्रोसेसिंग निर्देश में प्रीप्रोसेसिंग टोकन का एक क्रम होता है, जो एक # प्रीप्रोसेसिंग टोकन के साथ शुरू होता है जो (अनुवाद चरण 4 की शुरुआत में) या तो स्रोत फ़ाइल में पहला वर्ण होता है (वैकल्पिक रूप से श्वेत स्थान के बाद एक नया लाइन वर्ण होता है) या वह कम से कम एक नई-लाइन वर्ण वाली सफेद जगह का अनुसरण करता है, और अगले नए-पंक्ति वर्ण द्वारा समाप्त होता है।

एकमात्र संभावित विवाद अभिभावकीय अभिव्यक्ति है '(अनुवाद चरण 4 की शुरुआत में)', जिसका अर्थ यह हो सकता है कि हैश से पहले की टिप्पणियां अनुपस्थित होनी चाहिए क्योंकि वे चरण 4 के अंत तक रिक्त स्थान से प्रतिस्थापित नहीं होते हैं।

जैसा कि अन्य ने उल्लेख किया है, पूर्व-मानक सी प्रीप्रोसेसरों ने कई तरीकों से समान रूप से व्यवहार नहीं किया है, और प्रीप्रोसेसर निर्देशों में पहले और उन क्षेत्रों में से एक था जहां विभिन्न कंपाइलरों ने अलग-अलग चीजें कीं, जिसमें उनके आगे के रिक्त स्थान के साथ प्रीप्रोसेसर निर्देशों को पहचानना नहीं था। ।

यह उल्लेखनीय है कि टिप्पणियों का विश्लेषण करने से पहले बैकस्लैश-न्यूलाइन हटाने का काम होता है। नतीजतन, आपको //बैकस्लैश के साथ टिप्पणियों को समाप्त नहीं करना चाहिए ।


7

मुझे नहीं पता कि यह अधिक सामान्य क्यों नहीं है। निश्चित रूप से ऐसे समय होते हैं, जब मुझे प्रीप्रोसेसर निर्देशों को इंडेंट करना पसंद होता है।

एक चीज जो मेरे रास्ते में आती रहती है (और कभी-कभी मुझे कोशिश करना बंद करने के लिए आश्वस्त करती है) यह है कि कई या अधिकांश संपादक / आईडीई निर्देश को कॉलम 1 में थोड़ी सी भी उकसावे पर फेंक देंगे। जो नरक के रूप में कष्टप्रद है।


5

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

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

#if COND1
void foo() {
  #if COND2
  int i;
    #if COND3
  i = someFunction()
  cout << i << eol;
    #endif
  #endif
}
#endif

14
यह कोड अजीब लग रहा है, क्योंकि आपने इंडेंटेशन के दो "स्ट्रीम" बनाए हैं। मैं लाइन 4 को एक और स्तर पर इंडेंट करूंगा, और मैं लाइनों को 6 और 7 से दो और स्तरों पर इंडेंट करूंगा।
केविन लाॅटी

3
पूर्णतया सहमत। मैं कभी-कभी ब्रेसेस भी लगाता हूं तो # अगर लुक बिलकुल इफ की तरह है
baash05

3
मैं अपने कोड को व्यवस्थित करने के लिए बहुत कोशिश करता हूं ताकि इसमें उन हिस्सों में कोई #ifdef रेखा न हो जहां मेरे पास वास्तविक कोड है। इसके बजाय, अगर मुझे सशर्त सामान की आवश्यकता है, तो मैं या तो इसे फंक्स्ड आउट फ़ंक्शंस में रख दूंगा या मैक्रोज़ को बाहर कर दूंगा; यह एक बहुत स्पष्ट रास्ता है जो मुझे लगता है (ठीक है, कम से कम यह मेरे लिए है)। आदर्श रूप से, उन सभी फैक्टर आउट पार्ट्स अन्य फ़ाइलों (हेडर या सशर्त रूप से संकलित स्रोत फ़ाइलों में होंगे; सामान्य "स्थिति" क्या कोड के लिए बनाया जा रहा है)।
डोनल फेलो

2
मैं लाइनों को 4 एक स्तर, और लाइनों 6 और 7 दो स्तरों पर इंडेंट करूंगा।
राकेटमग्नेट

3

आपके द्वारा दिए गए उदाहरण के लिए इसे स्पष्ट करने के लिए इंडेंटेशन का उपयोग करना उचित हो सकता है, यह देखते हुए कि आपके पास ऐसे निर्देशन की जटिल संरचना है।

व्यक्तिगत रूप से मुझे लगता है कि उन्हें ज्यादातर समय के लिए प्रेरित नहीं रखना उपयोगी है, क्योंकि ये निर्देश आपके बाकी कोड से अलग-अलग संचालित होते हैं। #Ifdef जैसे निर्देश पूर्व-प्रोसेसर द्वारा संभाले जाते हैं, इससे पहले कि कंपाइलर कभी आपका कोड देखता है, इसलिए #ifdef निर्देश के बाद कोड का एक ब्लॉक भी संकलित नहीं किया जा सकता है ।

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


3
आईपी ​​के दृष्टिकोण से, किसी चीज़ के बीच अंतर क्या है जो संकलित नहीं है और कुछ ऐसा है जो एक जेएमपी के कारण नहीं पहुंचा है।
baash05

2

मैं इस समय कुछ कोड में काम कर रहा हूं जिसमें #defines, #ifdefs, #elses, #endifs, #etc का भयानक मिश्रण है। इन सभी को अक्सर सामान्य सी कोड के साथ मिलाया जाता है। # ऑडियंस के गैर-इंडेंटिंग से उन्हें पढ़ना मुश्किल हो जाता है। और गैर-इंडेंट #defines के साथ इंडेंटेड कोड का मिश्रण एक बुरा सपना है।

एक सामान्य समाधान निर्देशों पर टिप्पणी करना है, ताकि आप आसानी से जान सकें कि वे क्या संदर्भित करते हैं:

#ifdef FOO
/* a lot of code */
#endif /* FOO */

#ifndef FOO
/* a lot of code */
#endif /* not FOO */

6
मैंने उस शैली को देखा है, मेरा मालिक इसका उपयोग करता है। और, अपने कोड के बाकी की तरह, यह सिर्फ एक गड़बड़ करता है। यदि आपके () बयानों के बजाय और उन टिप्पणियों का उपयोग करके अपने सामान्य से सभी इंडेंटेशन को हटाने की कल्पना करें। आप शिकायत करेंगे कि आप आसानी से नहीं देख सकते कि वे क्या संदर्भित करते हैं।
राकेटमग्नेट

2

वर्तमान में उपलब्ध लगभग सभी सी / सीपीपी संकलक में यह प्रतिबंधित नहीं है। यह उपयोगकर्ता के लिए तय करना है कि आप कोड को कैसे संरेखित करना चाहते हैं। इतना खुश कोडिंग।


1
निर्णय का उत्तर। क्या आप कुछ विशिष्ट शैली गाइड संदर्भ जोड़कर इसे सुधार सकते हैं?
इथरड्रैगन
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.