टाइप पनिंग: Difference between revisions
No edit summary |
|||
Line 26: | Line 26: | ||
bind(sockfd, (struct sockaddr *)&sa, sizeof sa); | bind(sockfd, (struct sockaddr *)&sa, sizeof sa); | ||
</syntaxhighlight> | </syntaxhighlight> | ||
बर्कले सॉकेट लाइब्रेरी मूल रूप से इस तथ्य पर निर्भर करती है कि C (प्रोग्रामिंग लैंग्वेज) में, <code>struct sockaddr_in</code> के लिए एक पॉइंटर <code>struct sockaddr के लिए एक पॉइंटर में स्वतंत्र रूप से परिवर्तनीय है;</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</code>को संदर्भित करेगा (जहाँ <code>sa</code> प्रकार का है <code>struct sockaddr_in</code>) दूसरे शब्दों में, सॉकेट लाइब्रेरी [[बहुरूपता (कंप्यूटर विज्ञान)|बहुरूपता]] या वंशानुक्रम के अल्पविकसित रूप को लागू करने के लिए टाइप पनिंग का उपयोग करती है। | ||
प्रोग्रामिंग दुनिया में | प्रोग्रामिंग दुनिया में अधिकांशतः देखा जाता है कि "पैडेड" डेटा संरचनाओं का उपयोग विभिन्न प्रकार के मूल्यों को प्रभावी ढंग से एक ही स्टोरेज स्पेस में संग्रहीत करने की अनुमति देता है। यह अधिकांशतः तब देखा जाता है जब दो संरचनाओं का उपयोग अनुकूलन के लिए पारस्परिक विशिष्टता में किया जाता है। | ||
== फ़्लोटिंग-पॉइंट उदाहरण == | == फ़्लोटिंग-पॉइंट उदाहरण == | ||
टाइप पनिंग के सभी उदाहरणों में संरचनाएं | टाइप पनिंग के सभी उदाहरणों में संरचनाएं सम्मलित नहीं हैं, जैसा कि पिछले उदाहरण में था। मान लीजिए कि हम यह निर्धारित करना चाहते हैं कि [[ तैरनेवाला स्थल |चल बिन्दु]] संख्या ऋणात्मक है या नहीं। हम लिख सकते हैं: | ||
<syntaxhighlight lang="c"> | <syntaxhighlight lang="c"> | ||
Line 38: | Line 38: | ||
return x < 0.0; | return x < 0.0; | ||
}</syntaxhighlight> | }</syntaxhighlight> | ||
चूँकि, यह मानते हुए कि चल बिन्दु आधार तुलनाएँ होती हैं,और यह भी मानते हुए कि फ्लोट को [[IEEE फ़्लोटिंग-पॉइंट मानक|आईईईई]] [[ तैरनेवाला स्थल |चल बिन्दु]] संख्या मानक मानक के अनुसार दर्शाया गया है, और पूर्णांक 32 बिट चौड़े होते हैं, हम केवल पूर्णांक संचालन का उपयोग करके चल बिन्दु संख्या के [[साइन बिट]] को निकालने के लिए टाइप पनिंग में संलग्न हो सकते हैं: | |||
<syntaxhighlight lang="c"> | <syntaxhighlight lang="c"> | ||
Line 45: | Line 45: | ||
return *ui & 0x80000000; | return *ui & 0x80000000; | ||
}</syntaxhighlight> | }</syntaxhighlight> | ||
ध्यान दें कि व्यवहार बिल्कुल वैसा नहीं होगा: के विशेष | ध्यान दें कि व्यवहार बिल्कुल वैसा नहीं होगा: x के ऋणात्मक शून्य होने के विशेष स्थितियों में, पहला कार्यान्वयन <code>false परिणाम देता है</code>जबकि दूसरा कार्यान्वयन <code>true</code>साथ ही, पहला कार्यान्वयन वापस आ जाएगा<code>false</code>किसी भी [[NaN]] मान के लिए, किन्तु बाद वाला वापस आ सकता है <code>true</code>साइन बिट सेट के साथ NaN मानों के लिए। | ||
इस तरह की सजा सबसे ज्यादा खतरनाक होती है। जबकि पूर्व उदाहरण केवल संरचना लेआउट और सूचक परिवर्तनीयता के बारे में सी प्रोग्रामिंग भाषा द्वारा की गई गारंटी पर निर्भर था, बाद वाला उदाहरण किसी विशेष सिस्टम के हार्डवेयर के बारे में धारणाओं पर निर्भर करता है। कुछ स्थितियाँ, जैसे [[रीयल-टाइम कंप्यूटिंग]] | समय-महत्वपूर्ण कोड जो संकलक अन्यथा [[संकलक अनुकूलन]] में विफल रहता है, को खतरनाक कोड की आवश्यकता हो सकती है। इन मामलों में, [[टिप्पणी (कंप्यूटर प्रोग्रामिंग)]] में ऐसी सभी धारणाओं का दस्तावेजीकरण, और पोर्टेबिलिटी अपेक्षाओं को सत्यापित करने के लिए अभिकथन (कंप्यूटिंग) #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> | |||
== भाषा द्वारा == | == भाषा द्वारा == | ||
=== सी और सी ++ === | === सी और सी ++ === | ||
चल बिन्दु संख्याों के बिट-प्रस्तुतिकरण के बारे में धारणा के अलावा, उपरोक्त फ़्लोटिंग-पॉइंट टाइप-पनिंग उदाहरण सी भाषा की बाधाओं का भी उल्लंघन करता है कि कैसे वस्तुओं तक पहुँचा जा सकता है:<ref name= ISOs6.5/7>ISO/IEC 9899 :1999 s6.5/7</ref> घोषित प्रकार <code>x</code> है <code>float</code> किन्तु इसे प्रकार की अभिव्यक्ति के माध्यम से पढ़ा जाता है <code>unsigned int</code>. कई सामान्य प्लेटफार्मों पर, पॉइंटर पनिंग का यह उपयोग समस्याएँ पैदा कर सकता है यदि विभिन्न पॉइंटर्स [[डेटा संरचना संरेखण]] | मशीन-विशिष्ट तरीकों से संरेखित हैं। इसके अलावा, विभिन्न आकारों के पॉइंटर्स [[अलियासिंग (कंप्यूटिंग)]] कर सकते हैं, जिससे कंपाइलर द्वारा अनचेक की गई समस्याएं पैदा हो सकती हैं। यहां तक कि जब डेटा आकार और सूचक प्रतिनिधित्व मेल खाते हैं, हालांकि, कंपाइलर गैर-अलियासिंग बाधाओं पर अनुकूलन करने के लिए भरोसा कर सकते हैं जो अस्वीकृत एलियासिंग की उपस्थिति में असुरक्षित होगा। | |||
==== पॉइंटर्स का उपयोग ==== | ==== पॉइंटर्स का उपयोग ==== | ||
पॉइंटर्स का उपयोग करके टाइप-पनिंग पर एक सहज प्रयास प्राप्त किया जा सकता है: (निम्नलिखित उदाहरण प्रकार के लिए | पॉइंटर्स का उपयोग करके टाइप-पनिंग पर एक सहज प्रयास प्राप्त किया जा सकता है: (निम्नलिखित उदाहरण प्रकार के लिए आईईईई-754 बिट-प्रतिनिधित्व मानता है <code>float</code>.) | ||
<syntaxhighlight lang="c"> | <syntaxhighlight lang="c"> | ||
Line 78: | Line 76: | ||
|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>union</code>==== | ||
सी में, | सी में, किन्तु सी ++ में नहीं, कभी-कभी ए के माध्यम से टाइप पनिंग करना संभव होता है <code>union</code>. | ||
<syntaxhighlight lang="c"> | <syntaxhighlight lang="c"> | ||
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>). वही वाक्य रचनात्मक रूप से मान्य है किन्तु सी ++ में अपरिभाषित व्यवहार है, <ref>ISO/IEC 14882:2011 Section 9.5</ref> चूँकि , जहाँ केवल अंतिम-लिखित सदस्य a <code>union</code> कोई भी मूल्य माना जाता है। | ||
पनिंग प्रकार के अन्य उदाहरण के लिए, एक सरणी का स्ट्राइड देखें। | पनिंग प्रकार के अन्य उदाहरण के लिए, एक सरणी का स्ट्राइड देखें। | ||
Line 126: | Line 123: | ||
<वाक्यविन्यास प्रकाश लैंग = सी ++> | <वाक्यविन्यास प्रकाश लैंग = सी ++> | ||
कॉन्स्टेक्स बूल is_negative (फ्लोट x) नोएक्सेप्ट { | कॉन्स्टेक्स बूल is_negative (फ्लोट x) नोएक्सेप्ट { | ||
static_assert(std::numeric_limits<float>::is_iec559); // (केवल | static_assert(std::numeric_limits<float>::is_iec559); // (केवल आईईईई 754 पर सक्षम करें) | ||
ऑटो यूआई = | ऑटो यूआई = एसटीडी�:: बिट_कास्ट <एसटीडी�:: uint32_t> (एक्स); | ||
वापसी यूआई और 0x80000000; | वापसी यूआई और 0x80000000; | ||
}</syntaxhighlight> | }</syntaxhighlight> | ||
Line 156: | Line 153: | ||
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 बिट माना जाता है: | ||
Line 202: | Line 199: | ||
===सी#=== | ===सी#=== | ||
C Sharp (प्रोग्रामिंग लैंग्वेज)|C# (और अन्य .NET लैंग्वेज) में, टाइप सिस्टम के कारण टाइप पनिंग प्राप्त करना थोड़ा कठिन है, | C Sharp (प्रोग्रामिंग लैंग्वेज)|C# (और अन्य .NET लैंग्वेज) में, टाइप सिस्टम के कारण टाइप पनिंग प्राप्त करना थोड़ा कठिन है, किन्तु पॉइंटर्स या स्ट्रक्चर यूनियनों का उपयोग करके इसे फिर भी किया जा सकता है। | ||
==== संकेतक ==== | ==== संकेतक ==== | ||
Line 216: | Line 213: | ||
==== संरचना संघ ==== | ==== संरचना संघ ==== | ||
संरचना संघों को 'असुरक्षित' कोड की किसी भी धारणा के बिना अनुमति दी जाती है, | संरचना संघों को 'असुरक्षित' कोड की किसी भी धारणा के बिना अनुमति दी जाती है, किन्तु उन्हें एक नए प्रकार की परिभाषा की आवश्यकता होती है। | ||
<syntaxhighlight lang="csharp"> | <syntaxhighlight lang="csharp"> |
Revision as of 12:15, 27 June 2023
This article has multiple issues. Please help improve it or discuss these issues on the talk page. (Learn how and when to remove these template messages)
(Learn how and when to remove this template message)
|
कंप्यूटर विज्ञान में, टाइप पनिंग वह प्रोग्रामिंग तकनीक है, जो प्रोग्रामिंग भाषा के टाइप प्रणाली को विकृत या बाधित करती है, जो औपचारिक भाषा की सीमा के भीतर प्राप्त करना मुश्किल या असंभव हो जाता है।
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_addr
टाइप है struct 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 मानों के लिए।
इस तरह की सजा सबसे ज्यादा खतरनाक होती है। जबकि पूर्व उदाहरण केवल संरचना लेआउट और सूचक परिवर्तनीयता के बारे में सी प्रोग्रामिंग भाषा द्वारा की गई गारंटी पर निर्भर था, बाद वाला उदाहरण किसी विशेष सिस्टम के हार्डवेयर के बारे में धारणाओं पर निर्भर करता है। कुछ स्थितियाँ, जैसे रीयल-टाइम कंप्यूटिंग | समय-महत्वपूर्ण कोड जो संकलक अन्यथा संकलक अनुकूलन में विफल रहता है, को खतरनाक कोड की आवश्यकता हो सकती है। इन मामलों में, टिप्पणी (कंप्यूटर प्रोग्रामिंग) में ऐसी सभी धारणाओं का दस्तावेजीकरण, और पोर्टेबिलिटी अपेक्षाओं को सत्यापित करने के लिए अभिकथन (कंप्यूटिंग) #Static अभिकथन प्रारंभ करने से कोड को बनाए रखने में मदद मिलती है।
फ़्लोटिंग-पॉइंट पनिंग के व्यावहारिक उदाहरणों में क्वेक III द्वारा लोकप्रिय तेज़ उलटा वर्गमूल, पूर्णांक के रूप में तेज़ FP तुलना सम्मलित है,[1] और एक पूर्णांक के रूप में वृद्धि करके पड़ोसी मूल्यों को ढूँढना (कार्यान्वयन nextafter
).[2]
भाषा द्वारा
सी और सी ++
चल बिन्दु संख्याों के बिट-प्रस्तुतिकरण के बारे में धारणा के अलावा, उपरोक्त फ़्लोटिंग-पॉइंट टाइप-पनिंग उदाहरण सी भाषा की बाधाओं का भी उल्लंघन करता है कि कैसे वस्तुओं तक पहुँचा जा सकता है:[3] घोषित प्रकार x
है float
किन्तु इसे प्रकार की अभिव्यक्ति के माध्यम से पढ़ा जाता है unsigned int
. कई सामान्य प्लेटफार्मों पर, पॉइंटर पनिंग का यह उपयोग समस्याएँ पैदा कर सकता है यदि विभिन्न पॉइंटर्स डेटा संरचना संरेखण | मशीन-विशिष्ट तरीकों से संरेखित हैं। इसके अलावा, विभिन्न आकारों के पॉइंटर्स अलियासिंग (कंप्यूटिंग) कर सकते हैं, जिससे कंपाइलर द्वारा अनचेक की गई समस्याएं पैदा हो सकती हैं। यहां तक कि जब डेटा आकार और सूचक प्रतिनिधित्व मेल खाते हैं, हालांकि, कंपाइलर गैर-अलियासिंग बाधाओं पर अनुकूलन करने के लिए भरोसा कर सकते हैं जो अस्वीकृत एलियासिंग की उपस्थिति में असुरक्षित होगा।
पॉइंटर्स का उपयोग
पॉइंटर्स का उपयोग करके टाइप-पनिंग पर एक सहज प्रयास प्राप्त किया जा सकता है: (निम्नलिखित उदाहरण प्रकार के लिए आईईईई-754 बिट-प्रतिनिधित्व मानता है float
.)
bool is_negative(float x) {
uint32_t ui = *(uint32_t*)π
return ui & 0x80000000;
}
सी मानक के अलियासिंग नियम बताते हैं कि किसी वस्तु का संग्रहित मूल्य केवल एक संगत प्रकार के लवल्यू एक्सप्रेशन द्वारा ही पहुँचा जा सकता है।[4] प्रकार float
और uint32_t
संगत नहीं हैं, इसलिए इस कोड का व्यवहार अपरिभाषित व्यवहार है। हालांकि जीसीसी और एलएलवीएम पर यह विशेष कार्यक्रम अपेक्षित रूप से संकलित और चलता है, अधिक जटिल उदाहरण सख्त अलियासिंग द्वारा बनाई गई धारणाओं के साथ बातचीत कर सकते हैं और अवांछित व्यवहार को जन्म दे सकते हैं। विकल्प -fno-strict-aliasing
टाइप-पनिंग के इस रूप का उपयोग करके कोड के सही व्यवहार को सुनिश्चित करेगा, हालांकि अन्य प्रकार के पनिंग का उपयोग करने की अनुशंसा की जाती है।[5]
का उपयोग union
सी में, किन्तु सी ++ में नहीं, कभी-कभी ए के माध्यम से टाइप पनिंग करना संभव होता है 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.ui
हाल ही में दूसरे सदस्य को लिखने के बाद, my_union.d
, C में टाइप-पनिंग का अनुमत रूप है,[6] बशर्ते कि पढ़ा गया सदस्य उस मूल्य से बड़ा न हो जिसका मूल्य निर्धारित किया गया था (अन्यथा पढ़ने में अनिर्दिष्ट व्यवहार होता है[7]). वही वाक्य रचनात्मक रूप से मान्य है किन्तु सी ++ में अपरिभाषित व्यवहार है, [8] चूँकि , जहाँ केवल अंतिम-लिखित सदस्य a union
कोई भी मूल्य माना जाता है।
पनिंग प्रकार के अन्य उदाहरण के लिए, एक सरणी का स्ट्राइड देखें।
का उपयोग bit_cast
सी ++ 20 में, std::bit_cast
ऑपरेटर बिना किसी अपरिभाषित व्यवहार के टाइप पनिंग की अनुमति देता है। यह फ़ंक्शन को लेबल करने की भी अनुमति देता है constexpr
.
<वाक्यविन्यास प्रकाश लैंग = सी ++> कॉन्स्टेक्स बूल is_negative (फ्लोट x) नोएक्सेप्ट {
static_assert(std::numeric_limits<float>::is_iec559); // (केवल आईईईई 754 पर सक्षम करें) ऑटो यूआई = एसटीडी�:: बिट_कास्ट <एसटीडी�:: uint32_t> (एक्स); वापसी यूआई और 0x80000000;
}</syntaxhighlight>
पास्कल
एक संस्करण रिकॉर्ड एक डेटा प्रकार को कई प्रकार के डेटा के रूप में मानने की अनुमति देता है, जिसके आधार पर संस्करण को संदर्भित किया जा रहा है। निम्नलिखित उदाहरण में, पूर्णांक को 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 उस मशीन पर पढ़ने से सुरक्षित है जिस पर प्रोग्राम चल रहा है या ऑपरेटिंग सिस्टम चल रहा है।
सी/सी++ से कास्ट तकनीक की पुनर्व्याख्या पास्कल में भी काम करती है। यह उपयोगी हो सकता है, जब उदा। बाइट स्ट्रीम से डवर्ड्स पढ़ना, और हम उन्हें फ्लोट के रूप में देखना चाहते हैं। यहां एक कार्यशील उदाहरण दिया गया है, जहां हम एक फ्लोट के लिए एक ड्वॉर्ड की पुनर्व्याख्या करते हैं:
type
pReal = ^Real;
var
DW : DWord;
F : Real;
F := pReal(@DW)^;
सी#
C Sharp (प्रोग्रामिंग लैंग्वेज)|C# (और अन्य .NET लैंग्वेज) में, टाइप सिस्टम के कारण टाइप पनिंग प्राप्त करना थोड़ा कठिन है, किन्तु पॉइंटर्स या स्ट्रक्चर यूनियनों का उपयोग करके इसे फिर भी किया जा सकता है।
संकेतक
सी # केवल पॉइंटर्स को तथाकथित देशी प्रकारों की अनुमति देता है, यानी किसी भी आदिम प्रकार (को छोड़कर string
), एनम, एरे या स्ट्रक्चर जो केवल अन्य मूल प्रकारों से बना है। ध्यान दें कि पॉइंटर्स को केवल 'असुरक्षित' चिह्नित कोड ब्लॉक में ही अनुमति दी जाती है।
float pi = 3.14159;
uint piAsRawData = *(uint*)π
संरचना संघ
संरचना संघों को 'असुरक्षित' कोड की किसी भी धारणा के बिना अनुमति दी जाती है, किन्तु उन्हें एक नए प्रकार की परिभाषा की आवश्यकता होती है।
[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
}
संदर्भ
- ↑ Herf, Michael (December 2001). "मूलांक टोटके". stereopsis : graphics.
- ↑ "बेवकूफ फ्लोट ट्रिक्स". Random ASCII - tech blog of Bruce Dawson (in English). 24 January 2012.
- ↑ ISO/IEC 9899 :1999 s6.5/7
- ↑ "§ 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: [...]
- ↑ "जीसीसी बग - जीएनयू प्रोजेक्ट". gcc.gnu.org.
- ↑ "§ 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.
- ↑
"§ 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).
- ↑ 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