टाइप पनिंग: Difference between revisions

From Vigyanwiki
m (Deepak moved page पनिंग टाइप करें to टाइप पनिंग without leaving a redirect)
No edit summary
 
(13 intermediate revisions by 3 users not shown)
Line 4: Line 4:
}}
}}


[[कंप्यूटर विज्ञान]] में, टाइप पनिंग कोई भी प्रोग्रामिंग तकनीक है जो एक [[ प्रोग्रामिंग भाषा ]] के [[ प्रकार प्रणाली ]] को उलट देती है या बाधित कर देती है ताकि एक ऐसा प्रभाव प्राप्त किया जा सके जो औपचारिक भाषा की सीमा के भीतर हासिल करना मुश्किल या असंभव हो।
[[कंप्यूटर विज्ञान]] में, '''टाइप पनिंग''' वह प्रोग्रामिंग तकनीक होती है, जिसमे [[ प्रोग्रामिंग भाषा |प्रोग्रामिंग भाषा]] के [[ प्रकार प्रणाली |टाइप प्रणाली]] को विकृत या बाधित करती है, जो औपचारिक भाषा को सीमा के भीतर प्राप्त करना जटिल या असंभव होता है।


C (प्रोग्रामिंग लैंग्वेज) और [[C++]] में, [[ सूचक (कंप्यूटर प्रोग्रामिंग) ]] [[प्रकार रूपांतरण]] और जैसे निर्माण <code>[[union (computer science)|union]]</code> - सी ++ [[संदर्भ (कंप्यूटर विज्ञान)]] प्रकार रूपांतरण जोड़ता है और <code>reinterpret_cast</code> इस सूची में — कई प्रकार के प्रकार के दंड की अनुमति देने के लिए प्रदान किए जाते हैं, हालांकि कुछ प्रकार वास्तव में मानक भाषा द्वारा समर्थित नहीं होते हैं।
C और [[C++]] में, [[ सूचक (कंप्यूटर प्रोग्रामिंग) | सूचक]] [[प्रकार रूपांतरण]] जैसे निर्माण - C++ इस सूची मे [[संदर्भ (कंप्यूटर विज्ञान)|संदर्भ]] प्रकार रूपांतरण और <code>reinterpret_cast युग्मित करता है</code> — कई प्रकार की टाइप पनिंग की अनुमति देने के लिए प्रदान किया जाता है, चूँकि कुछ प्रकार वास्तव में मानक भाषा द्वारा समर्थित नहीं होते हैं।


[[ पास्कल (प्रोग्रामिंग भाषा) ]] प्रोग्रामिंग लैंग्वेज में, [[ भिन्न प्रकार ]] के साथ [[ रिकॉर्ड (कंप्यूटर विज्ञान) ]] का उपयोग एक विशेष डेटा प्रकार को एक से अधिक तरीके से या सामान्य रूप से अनुमति नहीं देने के लिए किया जा सकता है।
[[ पास्कल (प्रोग्रामिंग भाषा) |पास्कल प्रोग्रामिंग भाषा]] में, [[ भिन्न प्रकार ]]के [[ रिकॉर्ड (कंप्यूटर विज्ञान) |रिकॉर्ड]] का उपयोग विशेष डेटा टाइप को एक से अधिक विधियों से या सामान्य रूप से अनुमत प्रणाली से संसाधित करने के लिए किया जा सकता है।


== सॉकेट उदाहरण ==
== सॉकेट उदाहरण ==
प्रकार के पनिंग का एक उत्कृष्ट उदाहरण [[बर्कले सॉकेट]]्स इंटरफ़ेस में पाया जाता है। एक आईपी पते पर एक खुले लेकिन अप्रारंभीकृत सॉकेट को बाइंड करने का कार्य निम्नानुसार घोषित किया गया है:
टाइप पनिंग का एक उत्कृष्ट उदाहरण [[बर्कले सॉकेट]] अंतराफलक में पाया जाता है। एक विवृत, किन्तु अप्रारंभित सॉकेट को आईपी पते से बांधने का कार्य निम्नानुसार घोषित किया गया है:


<syntaxhighlight lang="c">
<syntaxhighlight lang="c">
Line 17: Line 17:
</syntaxhighlight>
</syntaxhighlight>


  <code>bind</code> ई> फ़ंक्शन को आमतौर पर निम्नानुसार कहा जाता है:
  बाइंड फलन को सामान्यतः इस प्रकार कहा जाता है:


<syntaxhighlight lang="c">
<syntaxhighlight lang="c">
Line 26: Line 26:
bind(sockfd, (struct sockaddr *)&sa, sizeof sa);
bind(sockfd, (struct sockaddr *)&sa, sizeof sa);
</syntaxhighlight>
</syntaxhighlight>
बर्कले सॉकेट लाइब्रेरी मूल रूप से इस तथ्य पर निर्भर करती है कि C (प्रोग्रामिंग लैंग्वेज) में, एक पॉइंटर to <code>struct sockaddr_in</code> एक सूचक के लिए स्वतंत्र रूप से परिवर्तनीय है <code>struct sockaddr</code>; और, इसके अलावा, कि दो संरचना प्रकार एक ही मेमोरी लेआउट साझा करते हैं। इसलिए, संरचना क्षेत्र के लिए एक संदर्भ <code>my_addr->sin_family</code> (कहाँ <code>my_addr</code> प्रकार का है <code>struct sockaddr*</code>) वास्तव में क्षेत्र को संदर्भित करेगा <code>sa.sin_family</code> (कहाँ <code>sa</code> प्रकार का है <code>struct sockaddr_in</code>). दूसरे शब्दों में, सॉकेट लाइब्रेरी [[बहुरूपता (कंप्यूटर विज्ञान)]] या वंशानुक्रम (ऑब्जेक्ट-ओरिएंटेड प्रोग्रामिंग) के एक अल्पविकसित रूप को लागू करने के लिए टाइप पनिंग का उपयोग करती है।
बर्कले सॉकेट लाइब्रेरी मूल रूप से इस तथ्य पर निर्भर करती है कि C प्रोग्रामिंग भाषा में, <code>struct sockaddr_in</code> के लिए एक पॉइंटर <code>struct sockaddr के लिए एक पॉइंटर में स्वतंत्र रूप से परिवर्तनीय होता है;</code>और, इसके अतिरिक्त, दोनों संरचना समान प्रकार से मेमोरी लेआउट साझा करते हैं। इसलिए, संरचना क्षेत्र <code>my_addr->sin_family</code> (जहाँ <code>my_addr</code><code>struct sockaddr*</code>प्रकार का है) का संदर्भ वास्तव में क्षेत्र <code>sa.sin_family (जहां sa struct sockaddr_in प्रकार का है) को संदर्भित करेगा।</code>दूसरे शब्दों में, सॉकेट लाइब्रेरी [[बहुरूपता (कंप्यूटर विज्ञान)|बहुरूपता]] या वंशानुक्रम के अल्पविकसित रूप को लागू करने के लिए टाइप पनिंग का उपयोग करती है।


प्रोग्रामिंग दुनिया में अक्सर देखा जाता है कि गद्देदार डेटा संरचनाओं का उपयोग प्रभावी रूप से एक ही भंडारण स्थान में विभिन्न प्रकार के मूल्यों के भंडारण की अनुमति देता है। यह अक्सर देखा जाता है जब अनुकूलन के लिए पारस्परिक विशिष्टता में दो संरचनाओं का उपयोग किया जाता है।
प्रोग्रामिंग को अधिकांशतः देखा जाता है कि "पैडेड" डेटा संरचनाओं का उपयोग विभिन्न प्रकार के मूल्यों को प्रभावी ढंग से एक ही भंडारण स्पेस में संग्रहीत करने की अनुमति देता है। यह अधिकांशतः तब देखा जाता है जब दो संरचनाओं का उपयोग अनुकूलन के लिए पारस्परिक विशिष्टता में किया जाता है।


== फ़्लोटिंग-पॉइंट उदाहरण ==
== चल बिंदु  उदाहरण ==


टाइप पनिंग के सभी उदाहरणों में संरचनाएं शामिल नहीं हैं, जैसा कि पिछले उदाहरण ने किया था। मान लीजिए कि हम यह निर्धारित करना चाहते हैं कि [[ तैरनेवाला स्थल ]] नंबर ऋणात्मक है या नहीं। हम लिख सकते हैं:
टाइप पनिंग के सभी उदाहरणों में संरचनाएं सम्मलित नहीं हैं, जैसा कि पिछले उदाहरण में था। मान लीजिए कि हम यह निर्धारित करना चाहते हैं कि [[ तैरनेवाला स्थल |चल बिन्दु]] संख्या ऋणात्मक है या नहीं। हम लिख सकते हैं:


<syntaxhighlight lang="c">
<syntaxhighlight lang="c">
Line 38: Line 38:
     return x < 0.0;
     return x < 0.0;
}</syntaxhighlight>
}</syntaxhighlight>
हालाँकि, यह मानते हुए कि फ़्लोटिंग-पॉइंट तुलनाएँ महंगी हैं, और यह भी मान लीजिए <code>float</code> [[IEEE फ़्लोटिंग-पॉइंट मानक]] के अनुसार दर्शाया गया है, और पूर्णांक 32 बिट चौड़े हैं, हम केवल पूर्णांक संचालन का उपयोग करके फ़्लोटिंग-पॉइंट नंबर के [[साइन बिट]] को निकालने के लिए टाइप पनिंग में संलग्न हो सकते हैं:
चूँकि, यह मानते हुए कि चल बिन्दु आधार तुलनाएँ होती हैं,और यह भी मानते हुए कि फ्लोट को [[IEEE फ़्लोटिंग-पॉइंट मानक|आईईईई]] [[ तैरनेवाला स्थल |चल बिन्दु]] संख्या मानक मानक के अनुसार दर्शाया गया है, और पूर्णांक 32 बिट चौड़े होते हैं, हम केवल पूर्णांक संचालन का उपयोग करके चल बिन्दु संख्या के [[साइन बिट]] को निकालने के लिए टाइप पनिंग में संलग्न हो सकते हैं:


<syntaxhighlight lang="c">
<syntaxhighlight lang="c">
Line 45: Line 45:
     return *ui & 0x80000000;
     return *ui & 0x80000000;
}</syntaxhighlight>
}</syntaxhighlight>
ध्यान दें कि व्यवहार बिल्कुल वैसा नहीं होगा: के विशेष मामले में <code>x</code> शून्य पर हस्ताक्षर किया जा रहा है, पहला कार्यान्वयन उपज देता है <code>false</code> जबकि दूसरा देता है <code>true</code>. साथ ही, पहला कार्यान्वयन वापस आ जाएगा <code>false</code> किसी भी [[NaN]] मान के लिए, लेकिन बाद वाला वापस आ सकता है <code>true</code> साइन बिट सेट के साथ NaN मानों के लिए।
ध्यान दें कि व्यवहार बिल्कुल वैसा नहीं होगा: x के ऋणात्मक शून्य होने के विशेष स्थितियों में, पहला कार्यान्वयन <code>false परिणाम देता है</code>जबकि दूसरा कार्यान्वयन <code>true</code>साथ ही, पहला कार्यान्वयन वापस आ जाएगा<code>false</code>किसी भी [[NaN]] मान के लिए,<code>true</code> किन्तु बाद वाला साइन बिट के साथ NaN मानों के लिए <code>false</code> होता है।
 
इस तरह की सजा सबसे ज्यादा खतरनाक होती है। जबकि पूर्व उदाहरण केवल संरचना लेआउट और सूचक परिवर्तनीयता के बारे में सी प्रोग्रामिंग भाषा द्वारा की गई गारंटी पर निर्भर था, बाद वाला उदाहरण किसी विशेष सिस्टम के हार्डवेयर के बारे में धारणाओं पर निर्भर करता है। कुछ स्थितियाँ, जैसे [[रीयल-टाइम कंप्यूटिंग]] | समय-महत्वपूर्ण कोड जो संकलक अन्यथा [[संकलक अनुकूलन]] में विफल रहता है, को खतरनाक कोड की आवश्यकता हो सकती है। इन मामलों में, [[टिप्पणी (कंप्यूटर प्रोग्रामिंग)]] में ऐसी सभी धारणाओं का दस्तावेजीकरण, और पोर्टेबिलिटी अपेक्षाओं को सत्यापित करने के लिए अभिकथन (कंप्यूटिंग)#Static अभिकथन शुरू करने से कोड को बनाए रखने में मदद मिलती है।
 
फ़्लोटिंग-पॉइंट पनिंग के व्यावहारिक उदाहरणों में क्वेक III द्वारा लोकप्रिय तेज़ उलटा वर्गमूल, पूर्णांक के रूप में तेज़ FP तुलना शामिल है,<ref>{{cite web |last1=Herf |first1=Michael |title=मूलांक टोटके|url=http://stereopsis.com/radix.html |website=stereopsis : graphics |date=December 2001}}</ref> और एक पूर्णांक के रूप में वृद्धि करके पड़ोसी मूल्यों को ढूँढना (कार्यान्वयन {{code|nextafter}}).<ref>{{cite web |title=बेवकूफ फ्लोट ट्रिक्स|url=https://randomascii.wordpress.com/2012/01/23/stupid-float-tricks-2/ |website=Random ASCII - tech blog of Bruce Dawson |language=en |date=24 January 2012}}</ref>


इस प्रकार की पनिंग अन्य सभी से अधिक खतरनाक होती है। जबकि पूर्व उदाहरण केवल संरचना लेआउट और पॉइंटर परिवर्तनीयता के बारे में सी प्रोग्रामिंग भाषा द्वारा की गई गारंटी पर निर्भर करता था, बाद वाला उदाहरण किसी विशेष प्रणाली के हार्डवेयर के धारणाओं पर निर्भर करता है। कुछ स्थितियाँ, जैसे [[रीयल-टाइम कंप्यूटिंग]] समय- सूक्ष्म कोड जिसे संकलक अन्यथा [[संकलक अनुकूलन]] करने में विफल रहता है, के लिए खतरनाक कोड की आवश्यकता हो सकती है। इन स्थितियों में, [[टिप्पणी (कंप्यूटर प्रोग्रामिंग)|टिप्पणी]] में ऐसी सभी धारणाओं का दस्तावेजीकरण करना, और पोर्टेबिलिटी अपेक्षाओं को सत्यापित करने के लिए स्थैतिक प्रमाण प्रस्तुत करना, कोड को बनाए रखने में मदद करता है।


चल बिंदु पनिंग के व्यावहारिक उदाहरणों में क्वेक III द्वारा लोकप्रिय तेज़ वर्गमूल, पूर्णांक के रूप में FP तुलना <ref>{{cite web |last1=Herf |first1=Michael |title=मूलांक टोटके|url=http://stereopsis.com/radix.html |website=stereopsis : graphics |date=December 2001}}</ref> और एक पूर्णांक के रूप में वृद्धि करके निकटतम  मूल्यों को ढूँढना (कार्यान्वयन {{code|nextafter}}) सम्मलित है।<ref>{{cite web |title=बेवकूफ फ्लोट ट्रिक्स|url=https://randomascii.wordpress.com/2012/01/23/stupid-float-tricks-2/ |website=Random ASCII - tech blog of Bruce Dawson |language=en |date=24 January 2012}}</ref>
== भाषा द्वारा ==
== भाषा द्वारा ==


=== सी और सी ++ ===
=== सी और सी ++ ===


फ़्लोटिंग-पॉइंट नंबरों के बिट-प्रस्तुतिकरण के बारे में धारणा के अलावा, उपरोक्त फ़्लोटिंग-पॉइंट टाइप-पनिंग उदाहरण सी भाषा की बाधाओं का भी उल्लंघन करता है कि कैसे वस्तुओं तक पहुँचा जा सकता है:<ref name= ISOs6.5/7>ISO/IEC 9899 :1999 s6.5/7</ref> घोषित प्रकार <code>x</code> है <code>float</code> लेकिन इसे प्रकार की अभिव्यक्ति के माध्यम से पढ़ा जाता है <code>unsigned int</code>. कई सामान्य प्लेटफार्मों पर, पॉइंटर पनिंग का यह उपयोग समस्याएँ पैदा कर सकता है यदि विभिन्न पॉइंटर्स [[डेटा संरचना संरेखण]] | मशीन-विशिष्ट तरीकों से संरेखित हैं। इसके अलावा, विभिन्न आकारों के पॉइंटर्स [[अलियासिंग (कंप्यूटिंग)]] कर सकते हैं, जिससे कंपाइलर द्वारा अनचेक की गई समस्याएं पैदा हो सकती हैं। यहां तक ​​कि जब डेटा आकार और सूचक प्रतिनिधित्व मेल खाते हैं, हालांकि, कंपाइलर गैर-अलियासिंग बाधाओं पर अनुकूलन करने के लिए भरोसा कर सकते हैं जो अस्वीकृत एलियासिंग की उपस्थिति में असुरक्षित होगा।
चल बिन्दु संख्याों के बिट-प्रस्तुतिकरण के बारे में धारणा के अतिरिक्त , उपरोक्त चल बिंदु  टाइप-पनिंग उदाहरण भाषा की बाधाओं का भी उल्लंघन करता है कि कैसे वस्तुओं तक पहुँचा जा सकता है:<ref name= ISOs6.5/7>ISO/IEC 9899 :1999 s6.5/7</ref> <code>x</code> टाइप <code>float</code> है किन्तु  इसे <code>unsigned int</code> प्रकार की अभिव्यक्ति के माध्यम से पढ़ा जाता है। कई सामान्य प्लेटफार्मों पर, यदि अलग-अलग पॉइंटर्स को [[डेटा संरचना संरेखण|डेटा संरचना विधियों से संरेखित]] किया जाता है, तो पॉइंटर पनिंग का यह उपयोग समस्याएँ उत्पन्न कर सकता हैं। इसके अतिरिक्त, विभिन्न आकारों के पॉइंटर्स एक ही मेमोरी को [[अलियासिंग (कंप्यूटिंग)|अलियासिंग]] कर सकते हैं, जिससे संकलक द्वारा अनचेक की गई समस्याएं उत्पन्न हो सकती हैं। यहां तक ​​कि जब डेटा आकार और सूचक प्रतिनिधित्व मेल खाते हैं, चूँकि , संकलक अनुकूलन करने के लिए गैर-अलियासिंग बाधाओं पर अनुकूलन करने के लिए विश्‍वास कर सकते हैं जो अस्वीकृत एलियासिंग की उपस्थिति में असुरक्षित होता है।


==== पॉइंटर्स का उपयोग ====
==== सूचकों का प्रयोग ====


पॉइंटर्स का उपयोग करके टाइप-पनिंग पर एक सहज प्रयास प्राप्त किया जा सकता है: (निम्नलिखित उदाहरण प्रकार के लिए IEEE-754 बिट-प्रतिनिधित्व मानता है <code>float</code>.)
पॉइंटर्स का उपयोग करके टाइप-पनिंग का एक सरल प्रयास प्राप्त किया जा सकता है: (निम्न चल रहा उदाहरण टाइप<code>float</code>के लिए आईईईई-754 बिट-प्रतिनिधित्व करता है।)


<syntaxhighlight lang="c">
<syntaxhighlight lang="c">
Line 67: Line 65:
   return ui & 0x80000000;
   return ui & 0x80000000;
}</syntaxhighlight>
}</syntaxhighlight>
सी मानक के अलियासिंग नियम बताते हैं कि किसी वस्तु का संग्रहित मूल्य केवल एक संगत प्रकार के लवल्यू एक्सप्रेशन द्वारा ही पहुँचा जा सकता है।<ref>{{Citation
C मानक के अलियासिंग नियम बताते हैं कि किसी वस्तु का संग्रहित मूल्य केवल एक संगत प्रकार के लवल्यू अभिव्यक्ति द्वारा ही पहुँचा जा सकता है।<ref>{{Citation
|title=ISO/IEC 9899:2018
|title=ISO/IEC 9899:2018
|language=English
|language=English
Line 77: Line 75:
|chapter=§ 6.5/7
|chapter=§ 6.5/7
|page=55
|page=55
|quote=An object shall have its stored value accessed only by an lvalue expression that has one of the following types: [...]}}</ref> प्रकार <code>float</code> और <code>uint32_t</code> संगत नहीं हैं, इसलिए इस कोड का व्यवहार [[अपरिभाषित व्यवहार]] है। हालांकि जीसीसी और एलएलवीएम पर यह विशेष कार्यक्रम अपेक्षित रूप से संकलित और चलता है, अधिक जटिल उदाहरण [[सख्त अलियासिंग]] द्वारा बनाई गई धारणाओं के साथ बातचीत कर सकते हैं और अवांछित व्यवहार को जन्म दे सकते हैं। विकल्प <code>-fno-strict-aliasing</code> टाइप-पनिंग के इस रूप का उपयोग करके कोड के सही व्यवहार को सुनिश्चित करेगा, हालांकि अन्य प्रकार के पनिंग का उपयोग करने की अनुशंसा की जाती है।<ref>{{cite web |title=जीसीसी बग - जीएनयू प्रोजेक्ट|url=https://gcc.gnu.org/bugs/#nonbugs_c |website=gcc.gnu.org}}</ref>
|quote=An object shall have its stored value accessed only by an lvalue expression that has one of the following types: [...]}}</ref> टाइप  <code>float</code> और <code>uint32_t</code> संगत नहीं होता हैं, इसलिए इस कोड का व्यवहार [[अपरिभाषित व्यवहार|अपरिभाषित]] करता है। यद्यपि जीसीसी और एलएलवीएम पर यह विशेष कार्यक्रम अपेक्षित रूप से संकलित करता है, जटिल उदाहरण [[सख्त अलियासिंग]] द्वारा बनाई गई धारणाओं को कर सकते हैं और अवांछित व्यवहार को जन्म दे सकते हैं। विकल्प <code>-fno-strict-aliasing</code>टाइप-पनिंग के इस रूप का उपयोग करके कोड के सही व्यवहार को सुनिश्चित करेगा, चूँकि अन्य प्रकार के पनिंग का उपयोग करने की अनुशंसा की जाती है।<ref>{{cite web |title=जीसीसी बग - जीएनयू प्रोजेक्ट|url=https://gcc.gnu.org/bugs/#nonbugs_c |website=gcc.gnu.org}}</ref>
 


==== का उपयोग <code>union</code>====
==== यूनियन<code>का उपयोग</code>====


सी में, लेकिन सी ++ में नहीं, कभी-कभी के माध्यम से टाइप पनिंग करना संभव होता है <code>union</code>.
C में, किन्तु C ++ में नहीं, कभी-कभी <code>union</code>के माध्यम से टाइप पनिंग करना संभव होता है।


<syntaxhighlight lang="c">
<syntaxhighlight lang="c">
Line 93: Line 90:
     return my_union.ui & 0x80000000;
     return my_union.ui & 0x80000000;
}</syntaxhighlight>
}</syntaxhighlight>
एक्सेस करना <code>my_union.ui</code> हाल ही में दूसरे सदस्य को लिखने के बाद, <code>my_union.d</code>, C में टाइप-पनिंग का अनुमत रूप है,<ref>{{Citation
हाल ही में दूसरे इकाई <code>my_union.d</code> को लिखने के बाद, <code>my_union.ui, तक पहुंचना</code>C में टाइप-पनिंग का एक अनुमत रूप होता है,<ref>{{Citation
|title=ISO/IEC 9899:2018
|title=ISO/IEC 9899:2018
|language=English
|language=English
Line 104: Line 101:
|page=59
|page=59
|quote=If the member used to read the contents of a union object is not the same as the member last used to store a value in the object, the appropriate part of the object representation of the value is reinterpreted as an object representation in the new type as described in 6.2.6 (''a process sometimes called “type punning”''). '''This might be a trap representation.'''
|quote=If the member used to read the contents of a union object is not the same as the member last used to store a value in the object, the appropriate part of the object representation of the value is reinterpreted as an object representation in the new type as described in 6.2.6 (''a process sometimes called “type punning”''). '''This might be a trap representation.'''
}}</ref> बशर्ते कि पढ़ा गया सदस्य उस मूल्य से बड़ा न हो जिसका मूल्य निर्धारित किया गया था (अन्यथा पढ़ने में [[अनिर्दिष्ट व्यवहार]] होता है<ref>
}}</ref> बशर्ते कि पढ़ा गया इकाई उस मूल्य से बड़ा न हो जिसका मूल्य निर्धारित किया गया था (अन्यथा पढ़ने में [[अनिर्दिष्ट व्यवहार]] होता है<ref>
{{Citation
{{Citation
|title=ISO/IEC 9899:2018
|title=ISO/IEC 9899:2018
Line 116: Line 113:
|page=403
|page=403
|quote=The following are unspecified: … The values of bytes that correspond to union members ''other than the one last stored into'' (6.2.6.1).
|quote=The following are unspecified: … The values of bytes that correspond to union members ''other than the one last stored into'' (6.2.6.1).
}}</ref>). वही वाक्य रचनात्मक रूप से मान्य है लेकिन सी ++ में अपरिभाषित व्यवहार है, <ref>ISO/IEC 14882:2011 Section 9.5</ref> हालाँकि, जहाँ केवल अंतिम-लिखित सदस्य a <code>union</code> कोई भी मूल्य माना जाता है।
}}</ref>) यह वाक्यविन्यास की दृष्टि से मान्य है, किन्तु  C++ में इसका व्यवहार अपरिभाषित है, <ref>ISO/IEC 14882:2011 Section 9.5</ref> चूँकि, जहाँ केवल अंतिम-लिखित इकाई को ही कोई मूल्य माना जाता है।


पनिंग प्रकार के अन्य उदाहरण के लिए, एक सरणी का स्ट्राइड देखें।
टाइप पनिंग के एक अन्य उदाहरण के लिए, किसी सरणी का चरण देखें।


==== का उपयोग <code>bit_cast</code> ====
==== <code>बिट_कास्ट का उपयोग</code> ====
 
[[सी ++ 20]] में, <code>std::bit_cast</code> ऑपरेटर बिना किसी अपरिभाषित व्यवहार के टाइप पनिंग की अनुमति देता है। यह फ़ंक्शन को लेबल करने की भी अनुमति देता है <code>constexpr</code>.
 
<वाक्यविन्यास प्रकाश लैंग = सी ++>
कॉन्स्टेक्स बूल is_negative (फ्लोट x) नोएक्सेप्ट {
  static_assert(std::numeric_limits<float>::is_iec559); // (केवल IEEE 754 पर सक्षम करें)
  ऑटो यूआई = एसटीडी :: बिट_कास्ट <एसटीडी :: uint32_t> (एक्स);
  वापसी यूआई और 0x80000000;
}</syntaxhighlight>


[[सी ++ 20]] में, <code>std::bit_cast</code> संचालक बिना किसी अपरिभाषित व्यवहार के टाइप पनिंग की अनुमति देता है। यह फलन को कॉन्स्टेक्सपीआर लेबल करने की भी अनुमति देता है।
  static_assert(std::numeric_limits<float>::is_iec559); //(केवल आईईईई 754 पर सक्षम करें)
  auto ui = std�:: bit_cast<std�:: uint32_t> (x);
  return ui & 0x80000000;
=== पास्कल ===
=== पास्कल ===
एक संस्करण रिकॉर्ड एक डेटा प्रकार को कई प्रकार के डेटा के रूप में मानने की अनुमति देता है, जिसके आधार पर संस्करण को संदर्भित किया जा रहा है। निम्नलिखित उदाहरण में, पूर्णांक को 16 बिट माना जाता है, जबकि देशांतर और वास्तविक को 32 माना जाता है, जबकि चरित्र को 8 बिट माना जाता है:
एक संस्करण रिकॉर्ड डेटा टाइप को कई प्रकार के डेटा के रूप में मानने की अनुमति देता है, जो इस पर निर्भर करता है कि किस प्रकार का संदर्भ दिया जा रहा है। निम्नलिखित उदाहरण में, पूर्णांक को 16 बिट माना जाता है, जबकि लॉन्गिंट और रियल को 32 माना जाता है, जबकि कैरेक्टर को 8 बिट माना जाता है:
<syntaxhighlight lang="pascal">
<syntaxhighlight lang="pascal">
type
type
Line 156: Line 148:
LA    := V.L;    (* this would store a Real into an Integer *)
LA    := V.L;    (* this would store a Real into an Integer *)
</syntaxhighlight>
</syntaxhighlight>
पास्कल में, एक वास्तविक को एक पूर्णांक में कॉपी करने से यह छोटा मूल्य में परिवर्तित हो जाता है। यह विधि फ़्लोटिंग-पॉइंट नंबर के बाइनरी मान को एक लंबे पूर्णांक (32 बिट) के रूप में अनुवादित करेगी, जो समान नहीं होगा और कुछ सिस्टम पर लंबे पूर्णांक मान के साथ असंगत हो सकता है।
पास्कल में, एक वास्तविक को एक पूर्णांक में कॉपी करने से यह छोटा मूल्य में परिवर्तित हो जाता है। यह विधि चल बिन्दु संख्या के बाइनरी मान को एक लंबे पूर्णांक (32 बिट) के रूप में अनुवादित करेगी, जो समान नहीं होगा और कुछ प्रणाली  पर लंबे पूर्णांक मान के साथ असंगत हो सकता है।


इन उदाहरणों का उपयोग अजीब रूपांतरण बनाने के लिए किया जा सकता है, हालांकि, कुछ मामलों में, इस प्रकार के निर्माणों के लिए वैध उपयोग हो सकते हैं, जैसे डेटा के विशेष टुकड़ों के स्थान निर्धारित करने के लिए। निम्नलिखित उदाहरण में एक सूचक और एक देशांतर दोनों को 32 बिट माना जाता है:
इन उदाहरणों का उपयोग अजीब रूपांतरण बनाने के लिए किया जा सकता है, चूँकि, कुछ स्थितियों में, इस प्रकार के निर्माणों के लिए वैध उपयोग हो सकते हैं, जैसे डेटा के विशेष टुकड़ों के स्थान निर्धारित करने के लिए। निम्नलिखित उदाहरण में एक सूचक और एक देशांतर दोनों को 32 बिट माना जाता है:
<syntaxhighlight lang="pascal">
<syntaxhighlight lang="pascal">
type
type
Line 178: Line 170:
WriteLn('Variable PP is located at address ', Hex(PP^.L));
WriteLn('Variable PP is located at address ', Hex(PP^.L));
</syntaxhighlight>
</syntaxhighlight>
जहाँ नया पास्कल में एक सूचक के लिए स्मृति आवंटित करने के लिए मानक दिनचर्या है, और हेक्स संभवतः एक पूर्णांक के मान का वर्णन करने वाले हेक्साडेसिमल स्ट्रिंग को प्रिंट करने के लिए एक नियमित है। यह एक सूचक के पते को प्रदर्शित करने की अनुमति देगा, जिसे सामान्य रूप से अनुमति नहीं है। (पॉइंटर्स को पढ़ा या लिखा नहीं जा सकता है, केवल असाइन किया जा सकता है।) पॉइंटर के एक पूर्णांक संस्करण के लिए मान निर्दिष्ट करने से सिस्टम मेमोरी में किसी भी स्थान पर जांच या लिखने की अनुमति होगी:
जहाँ पास्कल में एक सूचक के लिए स्मृति आवंटित करने के लिए मानक दिनचर्या है, और हेक्स संभवतः एक पूर्णांक के मान का वर्णन करने वाले हेक्साडेसिमल स्ट्रिंग को प्रिंट करने के लिए एक नियमित है। यह एक सूचक के पते को प्रदर्शित करने की अनुमति देगा, जिसे सामान्य रूप से अनुमति नहीं है। (बिन्दुओ को पढ़ा या लिखा नहीं जा सकता है, केवल असाइन किया जा सकता है।) सूचक के एक पूर्णांक संस्करण के लिए मान निर्दिष्ट करने से प्रणाली  मेमोरी में किसी भी स्थान पर जांच या लिखने की अनुमति होती है :
<syntaxhighlight lang="pascal">
<syntaxhighlight lang="pascal">
PP^.L := 0;
PP^.L := 0;
Line 185: Line 177:
WriteLn('Word 0 of this machine contains ', K);
WriteLn('Word 0 of this machine contains ', K);
</syntaxhighlight>
</syntaxhighlight>
यह निर्माण प्रोग्राम की जाँच या सुरक्षा उल्लंघन का कारण बन सकता है यदि पता 0 उस मशीन पर पढ़ने से सुरक्षित है जिस पर प्रोग्राम चल रहा है या ऑपरेटिंग सिस्टम चल रहा है।
यह निर्माण प्रोग्राम की जाँच या सुरक्षा उल्लंघन का कारण बन सकता है यदि 0 उस मशीन पर पढ़ने से सुरक्षित है जिस पर प्रोग्राम चल रहा है या संचालन प्रणाली के तहत चल रहा है।


सी/सी++ से कास्ट तकनीक की पुनर्व्याख्या पास्कल में भी काम करती है। यह उपयोगी हो सकता है, जब उदा। बाइट स्ट्रीम से डवर्ड्स पढ़ना, और हम उन्हें फ्लोट के रूप में देखना चाहते हैं। यहां एक कार्यशील उदाहरण दिया गया है, जहां हम एक फ्लोट के लिए एक ड्वॉर्ड की पुनर्व्याख्या करते हैं:
C/C++ से पुनर्व्याख्या कास्ट तकनीक पास्कल में भी काम करती है। यह उपयोगी हो सकता है, जब उदा बाइट स्ट्रीम से डवर्ड्स पढ़ना, और हम उन्हें फ्लोट के रूप में देखना चाहते हैं। यहां एक कार्यशील उदाहरण दिया गया है, जहां हम एक फ्लोट में एक शब्द को दोबारा परिभाषित करते हैं:
<syntaxhighlight lang="pascal">
<syntaxhighlight lang="pascal">
type
type
Line 199: Line 191:
</syntaxhighlight>
</syntaxhighlight>


===C#===


===सी#===
C# (और अन्य .NET भाषाओं) में, टाइप प्रणाली के कारण टाइप पनिंग प्राप्त करना थोड़ा कठिन है, किन्तु फिर भी सूचक या संरचना यूनियनों का उपयोग करके इसे किया जा सकता है।
 
C Sharp (प्रोग्रामिंग लैंग्वेज)|C# (और अन्य .NET लैंग्वेज) में, टाइप सिस्टम के कारण टाइप पनिंग हासिल करना थोड़ा कठिन है, लेकिन पॉइंटर्स या स्ट्रक्चर यूनियनों का उपयोग करके इसे फिर भी किया जा सकता है।


==== संकेतक ====
==== संकेतक ====


सी # केवल पॉइंटर्स को तथाकथित देशी प्रकारों की अनुमति देता है, यानी किसी भी आदिम प्रकार (को छोड़कर <code>string</code>), एनम, एरे या स्ट्रक्चर जो केवल अन्य मूल प्रकारों से बना है। ध्यान दें कि पॉइंटर्स को केवल 'असुरक्षित' चिह्नित कोड ब्लॉक में ही अनुमति दी जाती है।
C# केवल तथाकथित मूल प्रकारों के लिए पॉइंटर्स की अनुमति देता है, अर्थात किसी भी अभाज्य प्रकार (को छोड़कर <code>string</code>), एनम, एरे या संरचना जो केवल अन्य मूल प्रकारों से बना होता है। ध्यान दें कि पॉइंटर्स की अनुमति केवल 'असुरक्षित' चिह्नित कोड ब्लॉक में ही होती है।


<syntaxhighlight lang="csharp">
<syntaxhighlight lang="csharp">
Line 212: Line 203:
uint piAsRawData = *(uint*)&pi;
uint piAsRawData = *(uint*)&pi;
</syntaxhighlight>
</syntaxhighlight>
==== यूनियन संरचना ====


 
यूनियन संरचना को 'असुरक्षित' कोड की किसी भी धारणा के बिना अनुमति दी जाती है, किन्तु  उन्हें एक नए प्रकार की परिभाषा की आवश्यकता होती है।
==== संरचना संघ ====
 
संरचना संघों को 'असुरक्षित' कोड की किसी भी धारणा के बिना अनुमति दी जाती है, लेकिन उन्हें एक नए प्रकार की परिभाषा की आवश्यकता होती है।


<syntaxhighlight lang="csharp">
<syntaxhighlight lang="csharp">
Line 236: Line 225:
</syntaxhighlight>
</syntaxhighlight>


==== रॉ सीआईएल कोड ====


==== कच्चा सीआईएल कोड ====
C# के स्थान पर रॉ [[ सामान्य मध्यवर्ती भाषा |सामान्य मध्यवर्ती भाषा]] का उपयोग किया जा सकता है, क्योंकि इसमें अधिकांश प्रकार की सीमाएँ नहीं हैं। उदाहरण के लिए, यह किसी को सामान्य प्रकार के दो एनम मानों को संयोजित करने की अनुमति देता है:
 
C# के बजाय रॉ [[ सामान्य मध्यवर्ती भाषा ]] का उपयोग किया जा सकता है, क्योंकि इसमें अधिकांश प्रकार की सीमाएँ नहीं हैं। यह एक को, उदाहरण के लिए, एक सामान्य प्रकार के दो एनम मानों को संयोजित करने की अनुमति देता है:


<syntaxhighlight lang="csharp">
<syntaxhighlight lang="csharp">
Line 246: Line 234:
TEnum combined = a | b; // illegal
TEnum combined = a | b; // illegal
</syntaxhighlight>
</syntaxhighlight>
इसे निम्नलिखित सीआईएल कोड से रोका जा सकता है:
इसे निम्नलिखित सीआईएल कोड द्वारा गतिरोध उत्पन्न किया जा सकता है:


<syntaxhighlight lang="csharp">
<syntaxhighlight lang="csharp">
Line 264: Line 252:
</syntaxhighlight>
</syntaxhighlight>


  <code>cpblk</code> e> CIL ऑपकोड कुछ अन्य युक्तियों की अनुमति देता है, जैसे किसी संरचना को बाइट सरणी में बदलना:
  <code>cpblk</code> e> CIL ऑपकोड कुछ अन्य युक्तियों की अनुमति देता है, जैसे किसी संरचना को बाइट सरणी में बदलना होता है:


<syntaxhighlight lang="csharp">
<syntaxhighlight lang="csharp">
Line 297: Line 285:
}
}
</syntaxhighlight>
</syntaxhighlight>


==संदर्भ==
==संदर्भ==
Line 307: Line 294:
*[http://www.open-std.org/jtc1/sc22/wg14/www/docs/dr_257.htm Defect Report 257] to the [[C99]] standard, incidentally defining "type punning" in terms of <code>union</code>, and discussing the issues surrounding the implementation-defined behavior of the last example above
*[http://www.open-std.org/jtc1/sc22/wg14/www/docs/dr_257.htm Defect Report 257] to the [[C99]] standard, incidentally defining "type punning" in terms of <code>union</code>, and discussing the issues surrounding the implementation-defined behavior of the last example above
*[http://www.open-std.org/jtc1/sc22/wg14/www/docs/dr_283.htm Defect Report 283] on the use of unions for type punning
*[http://www.open-std.org/jtc1/sc22/wg14/www/docs/dr_283.htm Defect Report 283] on the use of unions for type punning
[[Category: प्रोग्रामिंग का निर्माण]] [[Category: उदाहरण सी कोड वाले लेख]] [[Category: पास्कल कोड उदाहरण के साथ लेख]]


[[Category: Machine Translated Page]]
[[Category:All articles needing additional references]]
[[Category:All articles with style issues]]
[[Category:Articles needing additional references from October 2011]]
[[Category:Articles with invalid date parameter in template]]
[[Category:Articles with multiple maintenance issues]]
[[Category:CS1 English-language sources (en)]]
[[Category:Created On 16/06/2023]]
[[Category:Created On 16/06/2023]]
[[Category:Machine Translated Page]]
[[Category:Templates Vigyan Ready]]
[[Category:Wikipedia articles with style issues from October 2011]]
[[Category:उदाहरण सी कोड वाले लेख]]
[[Category:पास्कल कोड उदाहरण के साथ लेख]]
[[Category:प्रोग्रामिंग का निर्माण]]

Latest revision as of 16:35, 7 July 2023

कंप्यूटर विज्ञान में, टाइप पनिंग वह प्रोग्रामिंग तकनीक होती है, जिसमे प्रोग्रामिंग भाषा के टाइप प्रणाली को विकृत या बाधित करती है, जो औपचारिक भाषा को सीमा के भीतर प्राप्त करना जटिल या असंभव होता है।

C और C++ में, सूचक प्रकार रूपांतरण जैसे निर्माण - C++ इस सूची मे संदर्भ प्रकार रूपांतरण और reinterpret_cast युग्मित करता है — कई प्रकार की टाइप पनिंग की अनुमति देने के लिए प्रदान किया जाता है, चूँकि कुछ प्रकार वास्तव में मानक भाषा द्वारा समर्थित नहीं होते हैं।

पास्कल प्रोग्रामिंग भाषा में, भिन्न प्रकार के रिकॉर्ड का उपयोग विशेष डेटा टाइप को एक से अधिक विधियों से या सामान्य रूप से अनुमत प्रणाली से संसाधित करने के लिए किया जा सकता है।

सॉकेट उदाहरण

टाइप पनिंग का एक उत्कृष्ट उदाहरण बर्कले सॉकेट अंतराफलक में पाया जाता है। एक विवृत, किन्तु अप्रारंभित सॉकेट को आईपी पते से बांधने का कार्य निम्नानुसार घोषित किया गया है:

int bind(int sockfd, struct sockaddr *my_addr, socklen_t addrlen);
बाइंड फलन को सामान्यतः इस प्रकार कहा जाता है:
struct sockaddr_in sa = {0};
int sockfd = ...;
sa.sin_family = AF_INET;
sa.sin_port = htons(port);
bind(sockfd, (struct sockaddr *)&sa, sizeof sa);

बर्कले सॉकेट लाइब्रेरी मूल रूप से इस तथ्य पर निर्भर करती है कि C प्रोग्रामिंग भाषा में, struct sockaddr_in के लिए एक पॉइंटर struct sockaddr के लिए एक पॉइंटर में स्वतंत्र रूप से परिवर्तनीय होता है;और, इसके अतिरिक्त, दोनों संरचना समान प्रकार से मेमोरी लेआउट साझा करते हैं। इसलिए, संरचना क्षेत्र my_addr->sin_family (जहाँ my_addrstruct sockaddr*प्रकार का है) का संदर्भ वास्तव में क्षेत्र sa.sin_family (जहां sa struct sockaddr_in प्रकार का है) को संदर्भित करेगा।दूसरे शब्दों में, सॉकेट लाइब्रेरी बहुरूपता या वंशानुक्रम के अल्पविकसित रूप को लागू करने के लिए टाइप पनिंग का उपयोग करती है।

प्रोग्रामिंग को अधिकांशतः देखा जाता है कि "पैडेड" डेटा संरचनाओं का उपयोग विभिन्न प्रकार के मूल्यों को प्रभावी ढंग से एक ही भंडारण स्पेस में संग्रहीत करने की अनुमति देता है। यह अधिकांशतः तब देखा जाता है जब दो संरचनाओं का उपयोग अनुकूलन के लिए पारस्परिक विशिष्टता में किया जाता है।

चल बिंदु उदाहरण

टाइप पनिंग के सभी उदाहरणों में संरचनाएं सम्मलित नहीं हैं, जैसा कि पिछले उदाहरण में था। मान लीजिए कि हम यह निर्धारित करना चाहते हैं कि चल बिन्दु संख्या ऋणात्मक है या नहीं। हम लिख सकते हैं:

bool is_negative(float x) {
    return x < 0.0;
}

चूँकि, यह मानते हुए कि चल बिन्दु आधार तुलनाएँ होती हैं,और यह भी मानते हुए कि फ्लोट को आईईईई चल बिन्दु संख्या मानक मानक के अनुसार दर्शाया गया है, और पूर्णांक 32 बिट चौड़े होते हैं, हम केवल पूर्णांक संचालन का उपयोग करके चल बिन्दु संख्या के साइन बिट को निकालने के लिए टाइप पनिंग में संलग्न हो सकते हैं:

bool is_negative(float x) {
    unsigned int *ui = (unsigned int *)&x;
    return *ui & 0x80000000;
}

ध्यान दें कि व्यवहार बिल्कुल वैसा नहीं होगा: x के ऋणात्मक शून्य होने के विशेष स्थितियों में, पहला कार्यान्वयन false परिणाम देता हैजबकि दूसरा कार्यान्वयन trueसाथ ही, पहला कार्यान्वयन वापस आ जाएगाfalseकिसी भी NaN मान के लिए,true किन्तु बाद वाला साइन बिट के साथ NaN मानों के लिए false होता है।

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

चल बिंदु पनिंग के व्यावहारिक उदाहरणों में क्वेक III द्वारा लोकप्रिय तेज़ वर्गमूल, पूर्णांक के रूप में FP तुलना [1] और एक पूर्णांक के रूप में वृद्धि करके निकटतम मूल्यों को ढूँढना (कार्यान्वयन nextafter) सम्मलित है।[2]

भाषा द्वारा

सी और सी ++

चल बिन्दु संख्याों के बिट-प्रस्तुतिकरण के बारे में धारणा के अतिरिक्त , उपरोक्त चल बिंदु टाइप-पनिंग उदाहरण भाषा की बाधाओं का भी उल्लंघन करता है कि कैसे वस्तुओं तक पहुँचा जा सकता है:[3] x टाइप float है किन्तु इसे unsigned int प्रकार की अभिव्यक्ति के माध्यम से पढ़ा जाता है। कई सामान्य प्लेटफार्मों पर, यदि अलग-अलग पॉइंटर्स को डेटा संरचना विधियों से संरेखित किया जाता है, तो पॉइंटर पनिंग का यह उपयोग समस्याएँ उत्पन्न कर सकता हैं। इसके अतिरिक्त, विभिन्न आकारों के पॉइंटर्स एक ही मेमोरी को अलियासिंग कर सकते हैं, जिससे संकलक द्वारा अनचेक की गई समस्याएं उत्पन्न हो सकती हैं। यहां तक ​​कि जब डेटा आकार और सूचक प्रतिनिधित्व मेल खाते हैं, चूँकि , संकलक अनुकूलन करने के लिए गैर-अलियासिंग बाधाओं पर अनुकूलन करने के लिए विश्‍वास कर सकते हैं जो अस्वीकृत एलियासिंग की उपस्थिति में असुरक्षित होता है।

सूचकों का प्रयोग

पॉइंटर्स का उपयोग करके टाइप-पनिंग का एक सरल प्रयास प्राप्त किया जा सकता है: (निम्न चल रहा उदाहरण टाइपfloatके लिए आईईईई-754 बिट-प्रतिनिधित्व करता है।)

bool is_negative(float x) {
   uint32_t ui = *(uint32_t*)&pi;
   return ui & 0x80000000;
}

C मानक के अलियासिंग नियम बताते हैं कि किसी वस्तु का संग्रहित मूल्य केवल एक संगत प्रकार के लवल्यू अभिव्यक्ति द्वारा ही पहुँचा जा सकता है।[4] टाइप float और uint32_t संगत नहीं होता हैं, इसलिए इस कोड का व्यवहार अपरिभाषित करता है। यद्यपि जीसीसी और एलएलवीएम पर यह विशेष कार्यक्रम अपेक्षित रूप से संकलित करता है, जटिल उदाहरण सख्त अलियासिंग द्वारा बनाई गई धारणाओं को कर सकते हैं और अवांछित व्यवहार को जन्म दे सकते हैं। विकल्प -fno-strict-aliasingटाइप-पनिंग के इस रूप का उपयोग करके कोड के सही व्यवहार को सुनिश्चित करेगा, चूँकि अन्य प्रकार के पनिंग का उपयोग करने की अनुशंसा की जाती है।[5]

यूनियनका उपयोग

C में, किन्तु C ++ में नहीं, कभी-कभी unionके माध्यम से टाइप पनिंग करना संभव होता है।

bool is_negative(float x) {
    union {
        unsigned int ui;
        float d;
    } my_union;
    my_union.d = x;
    return my_union.ui & 0x80000000;
}

हाल ही में दूसरे इकाई my_union.d को लिखने के बाद, my_union.ui, तक पहुंचनाC में टाइप-पनिंग का एक अनुमत रूप होता है,[6] बशर्ते कि पढ़ा गया इकाई उस मूल्य से बड़ा न हो जिसका मूल्य निर्धारित किया गया था (अन्यथा पढ़ने में अनिर्दिष्ट व्यवहार होता है[7]) यह वाक्यविन्यास की दृष्टि से मान्य है, किन्तु C++ में इसका व्यवहार अपरिभाषित है, [8] चूँकि, जहाँ केवल अंतिम-लिखित इकाई को ही कोई मूल्य माना जाता है।

टाइप पनिंग के एक अन्य उदाहरण के लिए, किसी सरणी का चरण देखें।

बिट_कास्ट का उपयोग

सी ++ 20 में, std::bit_cast संचालक बिना किसी अपरिभाषित व्यवहार के टाइप पनिंग की अनुमति देता है। यह फलन को कॉन्स्टेक्सपीआर लेबल करने की भी अनुमति देता है।

  static_assert(std::numeric_limits<float>::is_iec559); //(केवल आईईईई 754 पर सक्षम करें)
  auto ui = std�:: bit_cast<std�:: uint32_t> (x);
  return ui & 0x80000000;

पास्कल

एक संस्करण रिकॉर्ड डेटा टाइप को कई प्रकार के डेटा के रूप में मानने की अनुमति देता है, जो इस पर निर्भर करता है कि किस प्रकार का संदर्भ दिया जा रहा है। निम्नलिखित उदाहरण में, पूर्णांक को 16 बिट माना जाता है, जबकि लॉन्गिंट और रियल को 32 माना जाता है, जबकि कैरेक्टर को 8 बिट माना जाता है:

type
    VariantRecord = record
        case RecType : LongInt of
            1: (I : array[1..2] of Integer);  (* not show here: there can be several variables in a variant record's case statement *)
            2: (L : LongInt               );
            3: (R : Real                  );
            4: (C : array[1..4] of Char   );
        end;

var
    V  : VariantRecord;
    K  : Integer;
    LA : LongInt;
    RA : Real;
    Ch : Character;


V.I[1] := 1;
Ch     := V.C[1];  (* this would extract the first byte of V.I *)
V.R    := 8.3;   
LA     := V.L;     (* this would store a Real into an Integer *)

पास्कल में, एक वास्तविक को एक पूर्णांक में कॉपी करने से यह छोटा मूल्य में परिवर्तित हो जाता है। यह विधि चल बिन्दु संख्या के बाइनरी मान को एक लंबे पूर्णांक (32 बिट) के रूप में अनुवादित करेगी, जो समान नहीं होगा और कुछ प्रणाली पर लंबे पूर्णांक मान के साथ असंगत हो सकता है।

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

type
    PA = ^Arec;

    Arec = record
        case RT : LongInt of
            1: (P : PA     );
            2: (L : LongInt);
        end;

var
    PP : PA;
    K  : LongInt;


New(PP);
PP^.P := PP;
WriteLn('Variable PP is located at address ', Hex(PP^.L));

जहाँ पास्कल में एक सूचक के लिए स्मृति आवंटित करने के लिए मानक दिनचर्या है, और हेक्स संभवतः एक पूर्णांक के मान का वर्णन करने वाले हेक्साडेसिमल स्ट्रिंग को प्रिंट करने के लिए एक नियमित है। यह एक सूचक के पते को प्रदर्शित करने की अनुमति देगा, जिसे सामान्य रूप से अनुमति नहीं है। (बिन्दुओ को पढ़ा या लिखा नहीं जा सकता है, केवल असाइन किया जा सकता है।) सूचक के एक पूर्णांक संस्करण के लिए मान निर्दिष्ट करने से प्रणाली मेमोरी में किसी भी स्थान पर जांच या लिखने की अनुमति होती है :

PP^.L := 0;
PP    := PP^.P;  (* PP now points to address 0     *)
K     := PP^.L;  (* K contains the value of word 0 *)
WriteLn('Word 0 of this machine contains ', K);

यह निर्माण प्रोग्राम की जाँच या सुरक्षा उल्लंघन का कारण बन सकता है यदि 0 उस मशीन पर पढ़ने से सुरक्षित है जिस पर प्रोग्राम चल रहा है या संचालन प्रणाली के तहत चल रहा है।

C/C++ से पुनर्व्याख्या कास्ट तकनीक पास्कल में भी काम करती है। यह उपयोगी हो सकता है, जब उदा बाइट स्ट्रीम से डवर्ड्स पढ़ना, और हम उन्हें फ्लोट के रूप में देखना चाहते हैं। यहां एक कार्यशील उदाहरण दिया गया है, जहां हम एक फ्लोट में एक शब्द को दोबारा परिभाषित करते हैं:

type
    pReal = ^Real;

var
    DW : DWord;
    F  : Real;

F := pReal(@DW)^;

C#

C# (और अन्य .NET भाषाओं) में, टाइप प्रणाली के कारण टाइप पनिंग प्राप्त करना थोड़ा कठिन है, किन्तु फिर भी सूचक या संरचना यूनियनों का उपयोग करके इसे किया जा सकता है।

संकेतक

C# केवल तथाकथित मूल प्रकारों के लिए पॉइंटर्स की अनुमति देता है, अर्थात किसी भी अभाज्य प्रकार (को छोड़कर string), एनम, एरे या संरचना जो केवल अन्य मूल प्रकारों से बना होता है। ध्यान दें कि पॉइंटर्स की अनुमति केवल 'असुरक्षित' चिह्नित कोड ब्लॉक में ही होती है।

float pi = 3.14159;
uint piAsRawData = *(uint*)&pi;

यूनियन संरचना

यूनियन संरचना को 'असुरक्षित' कोड की किसी भी धारणा के बिना अनुमति दी जाती है, किन्तु उन्हें एक नए प्रकार की परिभाषा की आवश्यकता होती है।

[StructLayout(LayoutKind.Explicit)]
struct FloatAndUIntUnion
{
    [FieldOffset(0)]
    public float DataAsFloat;

    [FieldOffset(0)]
    public uint DataAsUInt;
}

// ...

FloatAndUIntUnion union;
union.DataAsFloat = 3.14159;
uint piAsRawData = union.DataAsUInt;

रॉ सीआईएल कोड

C# के स्थान पर रॉ सामान्य मध्यवर्ती भाषा का उपयोग किया जा सकता है, क्योंकि इसमें अधिकांश प्रकार की सीमाएँ नहीं हैं। उदाहरण के लिए, यह किसी को सामान्य प्रकार के दो एनम मानों को संयोजित करने की अनुमति देता है:

TEnum a = ...;
TEnum b = ...;
TEnum combined = a | b; // illegal

इसे निम्नलिखित सीआईएल कोड द्वारा गतिरोध उत्पन्न किया जा सकता है:

.method public static hidebysig
    !!TEnum CombineEnums<valuetype .ctor ([mscorlib]System.ValueType) TEnum>(
        !!TEnum a,
        !!TEnum b
    ) cil managed
{
    .maxstack 2

    ldarg.0 
    ldarg.1
    or  // this will not cause an overflow, because a and b have the same type, and therefore the same size.
    ret
}
cpblk e> CIL ऑपकोड कुछ अन्य युक्तियों की अनुमति देता है, जैसे किसी संरचना को बाइट सरणी में बदलना होता है:
.method public static hidebysig
    uint8[] ToByteArray<valuetype .ctor ([mscorlib]System.ValueType) T>(
        !!T& v // 'ref T' in C#
    ) cil managed
{
    .locals init (
        [0] uint8[]
    )

    .maxstack 3

    // create a new byte array with length sizeof(T) and store it in local 0
    sizeof !!T
    newarr uint8
    dup           // keep a copy on the stack for later (1)
    stloc.0

    ldc.i4.0
    ldelema uint8

    // memcpy(local 0, &v, sizeof(T));
    // <the array is still on the stack, see (1)>
    ldarg.0 // this is the *address* of 'v', because its type is '!!T&'
    sizeof !!T
    cpblk

    ldloc.0
    ret
}

संदर्भ

  1. Herf, Michael (December 2001). "मूलांक टोटके". stereopsis : graphics.
  2. "बेवकूफ फ्लोट ट्रिक्स". Random ASCII - tech blog of Bruce Dawson (in English). 24 January 2012.
  3. ISO/IEC 9899 :1999 s6.5/7
  4. "§ 6.5/7" (PDF), ISO/IEC 9899:2018 (in English), 2018, p. 55, archived from the original (PDF) on 2018-12-30, An object shall have its stored value accessed only by an lvalue expression that has one of the following types: [...]
  5. "जीसीसी बग - जीएनयू प्रोजेक्ट". gcc.gnu.org.
  6. "§ 6.5.2.3/3, footnote 97" (PDF), ISO/IEC 9899:2018 (in English), 2018, p. 59, archived from the original (PDF) on 2018-12-30, If the member used to read the contents of a union object is not the same as the member last used to store a value in the object, the appropriate part of the object representation of the value is reinterpreted as an object representation in the new type as described in 6.2.6 (a process sometimes called "type punning"). This might be a trap representation.
  7. "§ J.1/1, bullet 11" (PDF), ISO/IEC 9899:2018 (in English), 2018, p. 403, archived from the original (PDF) on 2018-12-30, The following are unspecified: … The values of bytes that correspond to union members other than the one last stored into (6.2.6.1).
  8. ISO/IEC 14882:2011 Section 9.5


बाहरी संबंध

  • Section of the GCC manual on -fstrict-aliasing, which defeats some type punning
  • Defect Report 257 to the C99 standard, incidentally defining "type punning" in terms of union, and discussing the issues surrounding the implementation-defined behavior of the last example above
  • Defect Report 283 on the use of unions for type punning