रेस्ट्रिक्ट

From Vigyanwiki

सी (प्रोग्रामिंग लैंग्वेज) में, restrict एक कीवर्ड (कंप्यूटर प्रोग्रामिंग) है, जिसे C99 द्वारा प्रस्तुत किया गया है, [1] जिसका उपयोग पॉइंटर (कंप्यूटर प्रोग्रामिंग) डिक्लेरेशन में किया जा सकता है। इस प्रकार टाइप क्वालीफ़ायर को जोड़कर, एक प्रोग्रामर कम्पाइलर को संकेत देता है कि पॉइंटर के लाइफटाइम के लिए, उस ऑब्जेक्ट तक पहुंचने के लिए किसी अन्य पॉइंटर का उपयोग नहीं किया जाएगा जिस पर वह पॉइंट करता है। यह कंपाइलर को ऑप्टिमाइजेशन (उदाहरण के लिए, वैश्वीकरण) करने की अनुमति देता है जो अन्यथा संभव नहीं होता।

restrict कंपाइलर का ऑप्टिमाइजेशन की सहायता से पॉइंटर अलाइसिंग के प्रभाव को सीमित करता है। यदि इंटेंट की डिक्लेरेशन का पालन नहीं किया जाता है और ऑब्जेक्ट को एक इंडिपेंडेंट पॉइंटर द्वारा एक्सेस किया जाता है, तो इसके परिणामस्वरूप अनडिफाइंड बिहेवियर होगा।

ऑप्टिमाइजेशन

यदि कंपाइलर जानता है कि मेमोरी ब्लॉक में केवल एक पॉइंटर है, तो यह बेहतर ऑप्टीमाइज़्ड कोड तैयार कर सकता है। उदाहरण के लिए:

void updatePtrs(size_t *ptrA, size_t *ptrB, size_t *val)
{
  *ptrA += *val;
  *ptrB += *val;
}

उपरोक्त कोड में, पॉइंटर ptrA, ptrB, और val पॉइंटर एलियासिंग का संदर्भ हो सकता है, इसलिए कंपाइलर कम इष्टतम कोड उत्पन्न कर सकता है:

; Hypothetical RISC Machine.
ldr r12, [val]     ; Load memory at val to r12.
ldr r3, [ptrA]     ; Load memory at ptrA to r3.
add r3, r3, r12    ; Perform addition: r3 = r3 + r12.
str r3, [ptrA]     ; Store r3 to memory location ptrA, updating the value.
ldr r3, [ptrB]     ; 'load' may have to wait until preceding 'store' completes.
ldr r12, [val]     ; Have to load a second time to ensure consistency.
add r3, r3, r12
str r3, [ptrB]

हालाँकि, यदि restrict कीवर्ड का उपयोग किया जाता है और उपरोक्त फ़ंक्शन को इस प्रकार डिक्लेअर किया जाता है

void updatePtrs(size_t *restrict ptrA, size_t *restrict ptrB, size_t *restrict val);

तब कम्पाइलर को यह मानने की अनुमति है कि ptrA, ptrB, और val विभिन्न लोकेशन को इंगित करते हैं और एक पॉइंटर द्वारा रेफेरेंसेड मेमोरी लोकेशन को अपडेट करने से अन्य पॉइंटर्स द्वारा संदर्भित मेमोरी लोकेशन प्रभावित नहीं होंगे। प्रोग्रामर, कंपाइलर नहीं, यह सुनिश्चित करने के लिए उत्तरदायी है कि पॉइंटर्स आइडेंटिकल लोकेशन को इंगित नहीं करते हैं। कंपाइलर उदा. कोड को रीअरेंज कर सकता है, पहले सभी मेमोरी लोकेशन को लोड करता है, फिर रिजल्ट को मेमोरी में वापस लाने से पहले ऑपरेशन करें।

ldr r12, [val]  ; Note that val is now only loaded once.
ldr r3, [ptrA]  ; Also, all 'load's in the beginning ...
ldr r4, [ptrB]
add r3, r3, r12
add r4, r4, r12
str r3, [ptrA]  ; ... all 'store's in the end.
str r4, [ptrB]

उपरोक्त असेंबली कोड छोटा है क्योंकि val केवल एक बार लोड किया जाता है। इसके अतिरिक्त, चूंकि कंपाइलर कोड को अधिक स्वतंत्र रूप से रीअरेंज कर सकता है, इसलिए कंपाइलर तीव्रता से एक्सीक्यूट होने वाला कोड उत्पन्न कर सकता है। उपरोक्त उदाहरण के दूसरे वर्ज़न में, सभीstoreऑपरेशनloadसंचालन के बाद हो रहे हैं, यह सुनिश्चित करते हुए कि प्रोसेसर को कोड के बीच में ब्लॉक नहीं करना पड़ेगा जब तक कि storeऑपरेशन पूरे न हो जाएं।

ध्यान दें कि रियल जेनरेट किए गए कोड का व्यवहार भिन्न हो सकता है। उपरोक्त मिनी-एक्साम्पल के साथ लाभ छोटा होता है, और वास्तविक जीवन के केस में हैवी मेमोरी एक्सेस करने वाले लार्ज लूप वास्तव में रिस्ट्रिक्ट होने में मदद करते हैं।

जैसा कि ऊपर उल्लेख किया गया है, इनकरेक्ट कोड कैसे बिहेव करता है यह अनडिफाइंड बिहेवियर है, कंपाइलर केवल यह सुनिश्चित करता है कि जनरेटेड कोड ठीक से काम करता है यदि कोड डिक्लेरेशन ऑफ़ इंटेंट का पालन करता है।

C++ कंपाइलर्स द्वारा सपोर्ट

C++ में restrict के लिए स्टैण्डर्ड सपोर्ट नहीं है, लेकिन कई कंपाइलरों के एक्विवैलेन्ट होते हैं जो सामान्यतः C++ और C दोनों में काम करते हैं, जैसे कि जीएनयू कम्पाइलर कलेक्शन और क्लांग __restrict__, और विज़ुअल सी++ __declspec(restrict)। इसके साथ ही, __restrict उन तीन कंपाइलरों द्वारा सपोर्टेड है। इन अल्टरनेटिव कीवर्ड की एक्सएक्ट इंटरप्रिटेशन कम्पाइलर द्वारा भिन्न होती है:

  • जीसीसी और क्लैंग जैसे यूनिक्स-शैली कंपाइलरों में, __restrict और __restrict__ का अर्थ बिल्कुल उनके C समकक्ष के समान है। एक्सटेंशन में उन्हें रिफरेन्स टाइप और thisपर लागू करने की अनुमति देना सम्मिलित है। [2]
  • विज़ुअल सी++ में, एकाधिक नो-अलियास क्वालिफायर प्रदान किए जाते हैं:
    1. __declspec(restrict) फ़ंक्शन डिक्लेरेशन पर लागू होता है और हिंट देता है कि रिटर्न्ड पॉइंटर उपनाम नहीं है।
    2. __restrict का प्रयोग restrict लोकेशन पर किया जाता है, लेकिन restrict नो-अलियास हिंट जैसा प्रचारित नहीं होता है। इसे यूनियन टाइप के लिए भी विस्तारित किया गया है।

कम्पाइलर वार्निंग

इनकरेक्ट कोड को रोकने में मदद करने के लिए, कुछ कंपाइलर और अन्य टूल यह पता लगाने का प्रयास करते हैं कि ओवरलैपिंग आर्ग्युमेंट को पैरामीटर मार्क restrictवाले फ़ंक्शन में कब पास किया गया है। [3] सीईआरटी सी कोडिंग स्टैण्डर्ड restrictके दुरुपयोग पर विचार करता है और लाइब्रेरी फ़ंक्शंस को इसके (ईएक्सपी43-C) सॉफ़्टवेयर बग के प्रोबेबल सोर्स के रूप में चिह्नित किया गया है, हालाँकि नवंबर 2019 तक इसके कारण होने वाली किसी भी वलनेरेबिलिटीज़ का पता नहीं चला है। [4]


संदर्भ

  1. Drepper, Ulrich (October 23, 2007). "Memory part 5: What programmers can do". What every programmer should know about memory. lwn.net. ...The default aliasing rules of the C and C++ languages do not help the compiler making these decisions (unless restrict is used, all pointer accesses are potential sources of aliasing). This is why Fortran is still a preferred language for numeric programming: it makes writing fast code easier. (In theory the restrict keyword introduced into the C language in the 1999 revision should solve the problem. Compilers have not caught up yet, though. The reason is mainly that too much incorrect code exists which would mislead the compiler and cause it to generate incorrect object code.)
  2. "प्रतिबंधित सूचक". Using the GNU Compiler Collection (GCC).
  3. "Warning Options: -Wrestrict". GCC. Retrieved 19 November 2019.
  4. "EXP43-C. Avoid undefined behavior when using restrict-qualified pointers". SEI CERT C Coding Standard. Retrieved 19 November 2019.


बाहरी संबंध