GCC 7.3 - 3.10.6. Argument Prescan

3.10.6 तर्क प्रेस्कैन




gcc

3.10.6 तर्क प्रेस्कैन

मैक्रो तर्कों को मैक्रो बॉडी में प्रतिस्थापित करने से पहले उन्हें पूरी तरह से मैक्रो-विस्तारित किया जाता है, जब तक कि उन्हें अन्य टोकन के साथ कड़ा या चिपकाया नहीं जाता है। प्रतिस्थापन के बाद, मैक्रो के विस्तार के लिए प्रतिस्थापित तर्कों सहित पूरे मैक्रो बॉडी को फिर से स्कैन किया जाता है। परिणाम यह है कि उनमें मैक्रो कॉल का विस्तार करने के लिए तर्कों को दो बार स्कैन किया जाता है।

अधिकांश समय, इसका कोई प्रभाव नहीं होता है। यदि तर्क में कोई मैक्रो कॉल होता है, तो वे पहले स्कैन के दौरान विस्तारित होते हैं। इसलिए परिणाम में कोई मैक्रो कॉल नहीं है, इसलिए दूसरा स्कैन इसे नहीं बदलता है। यदि तर्क के रूप में प्रतिस्थापित किया गया था, जिसमें कोई प्रीस्कैन नहीं है, तो एकल शेष स्कैन समान मैक्रो कॉल ढूंढेगा और समान परिणाम देगा।

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

आप आश्चर्यचकित हो सकते हैं, “यदि इसका कोई अंतर नहीं है, तो प्रेस्कैन का उल्लेख क्यों करें? और इसे क्यों नहीं छोड़ना चाहिए और प्रीप्रोसेसर को तेज करना चाहिए? ”जवाब है कि प्रीस्कैन तीन विशेष मामलों में फर्क करता है:

  • नेस्टेड मैक्रो को कॉल करता है।

    हम कहते हैं कि मैक्रो को नेस्टेड कॉल तब होता है जब मैक्रो के तर्क में उस मैक्रो के लिए कॉल होता है। उदाहरण के लिए, यदि f एक मैक्रो है जो एक तर्क की अपेक्षा करता है, f (f (1)) f लिए नेस्टेड जोड़ी है। वांछित विस्तार f (1) विस्तार करके किया जाता है और प्रतिस्थापित किया जाता है कि f की परिभाषा में। प्रीस्कैन के कारण अपेक्षित परिणाम होता है। प्रीस्कैन के बिना, f (1) को एक तर्क के रूप में प्रतिस्थापित किया जाएगा, और f का आंतरिक उपयोग मुख्य स्कैन के दौरान एक अप्रत्यक्ष आत्म-संदर्भ के रूप में दिखाई देगा और इसका विस्तार नहीं किया जाएगा।

  • मैक्रोज़ जो दूसरे मैक्रोज़ को कहते हैं जो कड़े या सुरीले होते हैं।

    यदि किसी तर्क को कड़ा या संक्षिप्त किया जाता है, तो प्रीस्कैन उत्पन्न नहीं होता है। यदि आप किसी मैक्रो का विस्तार करना चाहते हैं , तो उसके विस्तार को कठोर या संक्षिप्त करें, तो आप ऐसा कर सकते हैं कि एक मैक्रो को किसी अन्य मैक्रो को कॉल करने के लिए जो स्ट्रिंगिंग या कॉन्सेप्टन करता है। उदाहरण के लिए, यदि आपके पास है

    #define AFTERX(x) X_ ## x
    #define XAFTERX(x) AFTERX(x)
    #define TABLESIZE 1024
    #define BUFSIZE TABLESIZE

    तब AFTERX(BUFSIZE) फैलता है, और XAFTERX(BUFSIZE) फैलता है। ( X_TABLESIZE लिए नहीं। X_TABLESIZE हमेशा एक पूर्ण विस्तार करता है।)

  • तर्कों में प्रयुक्त मैक्रोज़, जिनके विस्तार में अप्रतिबंधित कॉमा हैं।

    यह तर्क की गलत संख्या के साथ कहे जाने वाले दूसरे स्कैन पर विस्तारित मैक्रो का कारण बन सकता है। यहाँ एक उदाहरण है:

    #define foo  a,b
    #define bar(x) lose(x)
    #define lose(x) (1 + (x))

    हम bar(foo) को (1 + (foo)) में बदलना चाहेंगे, जो बाद में (1 + (a,b)) । इसके बजाय, bar(foo) lose(a,b) में फैलता है, और आपको एक त्रुटि मिलती है क्योंकि lose लिए एकल तर्क की आवश्यकता होती है। इस मामले में, समस्या को आसानी से उन्हीं कोष्ठकों द्वारा हल किया जाता है, जिनका उपयोग अंकगणितीय सेवाओं के दुरुपयोग को रोकने के लिए किया जाना चाहिए:

    #define foo (a,b)
    or
    #define bar(x) lose((x))

    कोष्ठक की अतिरिक्त जोड़ी foo की परिभाषा में कॉमा को तर्क विभाजक के रूप में व्याख्या करने से रोकती है।

अगला: तर्क में नयापन , पिछला: स्व-संदर्भात्मक मैक्रोज़ , ऊपर: मैक्रो नुकसान [ Contents ] [ Index ]