अहस्ताक्षरित ints के बारे में सबसे अच्छा अभ्यास क्या हैं?


43

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

हालाँकि मुझे दूसरे के कोड से पता चलता है कि ऐसा करने वाला कोई और नहीं है। वहाँ कुछ महत्वपूर्ण है कि मैं देख रहा हूँ?

संपादित करें: इस प्रश्न के बाद से मैंने यह भी देखा है कि सी में, सी + + के रूप में अपवादों को फेंकने के बजाय त्रुटियों के लिए नकारात्मक मान लौटाना सामान्य है।


26
बस के लिए बाहर देखो for(unsigned int n = 10; n >= 0; n --)(छोरों अनंत)
क्रिस बर्ट-ब्राउन

3
C और C ++ में, अहस्ताक्षरित ints ने अतिप्रवाह व्यवहार को परिभाषित किया है (modulo 2 ^ n)। साइन इन्ट्स नहीं। ऑप्टिमाइज़र तेजी से उस अपरिभाषित व्यवहार का शोषण करते हैं, जिससे कुछ मामलों में आश्चर्यजनक परिणाम सामने आते हैं।
स्टीव ३४

2
अच्छा प्रश्न! मुझे भी एक बार यूटेंस टी प्रतिबंधित सीमा का उपयोग करने के लिए लुभाया गया था, लेकिन पाया गया कि जोखिम / असुविधा ने कोई लाभ / सुविधा नहीं दी है। अधिकांश पुस्तकालयों, जैसा कि आपने कहा, नियमित रूप से इन्टस को स्वीकार करें जहां एक यूइंट करेगा। इससे काम करना मुश्किल हो जाता है, लेकिन यह भी सवाल भी पैदा होता है: क्या यह इसके लायक है? व्यवहार में (यह मानते हुए कि आप गूंगे तरीके से चीजों के बारे में नहीं जाते हैं), आपके पास शायद ही कभी -218 का मूल्य होगा जहां एक सकारात्मक उम्मीद की जाती है। वह -218 कहीं से आया होगा, है ना? और आप इसके मूल का पता लगा सकते हैं। कभी-कभार ही होता है। आपकी सहायता के लिए अभिकथन, अपवाद, कोड अनुबंध का उपयोग करें।
नौकरी

@William Ting: यदि यह केवल C / C ++ के बारे में है, तो आपको अपने प्रश्न में उपयुक्त टैग जोड़ना चाहिए।
सीजरगॉन

2
@ क्रिस: वास्तविकता में अनंत लूप समस्या कितनी महत्वपूर्ण है? मेरा मतलब है, अगर यह रिलीज में अपना रास्ता बनाता है, तो कोड स्पष्ट रूप से परीक्षण नहीं किया गया था। यहां तक ​​कि जब आपको पहली बार यह त्रुटि करने के लिए कुछ घंटों की आवश्यकता होती है, तो दूसरी बार आपको पता होना चाहिए कि जब आपका कोड लूप करना बंद नहीं करता है, तो आपको पहले क्या देखना चाहिए।
सुरक्षित करें

जवाबों:


28

वहाँ कुछ महत्वपूर्ण है कि मैं देख रहा हूँ?

जब गणना में हस्ताक्षरित और अहस्ताक्षरित दोनों प्रकार के साथ-साथ विभिन्न आकार शामिल होते हैं, तो प्रकार के प्रचार के नियम जटिल हो सकते हैं और अप्रत्याशित व्यवहार हो सकते हैं

मेरा मानना ​​है कि जावा के अहस्ताक्षरित प्रकारों को छोड़ने का यह मुख्य कारण है।


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

2
यह जावा के लिए 64-बिट अहस्ताक्षरित प्रकार को शामिल नहीं करने का एक अच्छा कारण था, और शायद 32-बिट अहस्ताक्षरित प्रकार को शामिल न करने का एक सभ्य कारण [हालांकि हस्ताक्षरित और अहस्ताक्षरित 32-बिट मानों को जोड़ने का अर्थ कठिन नहीं होगा - इस तरह के ऑपरेशन को केवल 64-बिट हस्ताक्षरित परिणाम प्राप्त करना चाहिए]। अनसाइन्ड टाइप्स से छोटी intऐसी कोई कठिनाई नहीं होगी, हालाँकि (क्योंकि कोई भी गणना बढ़ावा देगी int); मेरे पास अहस्ताक्षरित प्रकार की कमी के बारे में कहने के लिए कुछ भी अच्छा नहीं है।
Supercat

17

मुझे लगता है कि माइकल के पास एक वैध बिंदु है, लेकिन IMO यही कारण है कि हर कोई हर समय (विशेष रूप से for (int i = 0; i < max, i++) इंट का उपयोग करता है, हमने इसे इस तरह से सीखा है। जब ' प्रोग्रामिंग सीखने के लिए ' पुस्तक में हर एक उदाहरण intएक forलूप में उपयोग होता है , तो बहुत कम लोग कभी उस अभ्यास पर सवाल उठाएंगे।

दूसरा कारण यह है कि int25% से कम है uint, और हम सभी आलसी हैं ... ;-)


2
मैं शैक्षिक मुद्दे से सहमत हूं। अधिकांश लोगों को लगता है कि वे जो भी पढ़ते हैं , उस पर
Matthieu एम।

1
यह भी मुमकिन है कि हर कोई ++इंक्रीमेंट करते समय पोस्टफिक्स का उपयोग करता है , इस तथ्य के बावजूद कि उसके विशेष व्यवहार की शायद ही कभी आवश्यकता होती है और यहां तक ​​कि प्रतियों पर निरर्थक मंथन हो सकता है यदि लूप इंडेक्स एक इटरेटर या अन्य गैर-मूलभूत प्रकार (या कंपाइलर वास्तव में घना है) ।
अंडरस्कोर_ड

बस "के लिए कुछ न करें" (uint i = 10; मैं> = 0; --i) "। लूप वेरिएबल्स के लिए केवल इनट्स का उपयोग करना इस संभावना से बचता है।
डेविड थॉर्नले

11

प्रकार में एन्कोडिंग रेंज की जानकारी एक अच्छी बात है। यह संकलन समय पर उचित संख्या का उपयोग करने में सक्षम है।

कई आर्किटेक्चर के पास int-> floatरूपांतरणों से निपटने के लिए विशेष निर्देश हैं । से रूपांतरण unsignedधीमा (एक छोटा सा) हो सकता है


8

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


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

7

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

दुर्भाग्य से हर कोई इस बारे में बहुत सचेत नहीं है कि उनका कोड क्या संचार करता है, और शायद यही कारण है कि आप हर जगह ints देखते हैं, भले ही मान कम से कम शासन कर रहे हों।


4
लेकिन मैं एक महीने के लिए अपने मूल्यों को केवल १२ के माध्यम से प्रतिबंधित करना चाहता हूं। क्या मैं इसके लिए दूसरे प्रकार का उपयोग करता हूं? एक महीने के बारे में क्या? कुछ भाषाएं वास्तव में जैसे मूल्यों को प्रतिबंधित करने की अनुमति देती हैं। अन्य, जैसे .Net / C # कोड अनुबंध प्रदान करते हैं। निश्चित रूप से, गैर-नकारात्मक पूर्णांक अक्सर होते हैं, लेकिन इस प्रकार का समर्थन करने वाली अधिकांश भाषाएँ आगे प्रतिबंधों का समर्थन नहीं करती हैं। तो, क्या एक संकेत और त्रुटि जाँच के मिश्रण का उपयोग करना चाहिए, या बस त्रुटि जाँच के माध्यम से सब कुछ करना चाहिए? अधिकांश पुस्तकालयों ने यूंट के लिए नहीं पूछा जहां यह एक का उपयोग करने के लिए समझ में आएगा, इसलिए एक का उपयोग करना और कास्टिंग करना असुविधाजनक हो सकता है।
नौकरी

@ जॉब मैं कहूंगा कि आपको अपने महीनों पर किसी प्रकार के कंपाइलर / दुभाषिया लागू प्रतिबंध का उपयोग करना चाहिए। यह आपको सेट करने के लिए कुछ बॉयलरप्लेट दे सकता है, लेकिन भविष्य के लिए आपके पास एक लागू प्रतिबंध है जो त्रुटि को रोकता है और बहुत स्पष्टता से संचार करता है कि आप क्या अपेक्षा कर रहे हैं। त्रुटियों को रोकना और संचार को आसान बनाना, लागू करते समय असुविधा से बहुत अधिक महत्वपूर्ण है।
दारमाकर

1
"मैं एक महीने के लिए अपने मूल्यों को केवल 12 के माध्यम से 1 तक सीमित करना चाह सकता हूं" यदि आपके पास महीनों की तरह मूल्यों का एक सीमित सेट है, तो आपको एक एन्यूमरेशन प्रकार का उपयोग करना चाहिए, न कि कच्चे पूर्णांक।
जोश कैसवेल

6

मैं unsigned intसरणी सूचकांकों के लिए C ++ में उपयोग करता हूं , ज्यादातर, और किसी भी काउंटर के लिए जो 0. से शुरू होता है। मुझे लगता है कि यह स्पष्ट रूप से कहना अच्छा है "यह चर नकारात्मक नहीं हो सकता"।


14
आपको संभवतः c ++ में इसके लिए size_t का उपयोग करना चाहिए
JohnB

2
मुझे पता है, मैं अभी परेशान नहीं हो सकता।
क्वांट_देव

3

आपको इस बारे में परवाह करनी चाहिए जब आप एक पूर्णांक के साथ काम कर रहे होते हैं जो वास्तव में एक हस्ताक्षरित इंट की सीमा तक पहुंच सकता है या उससे अधिक हो सकता है। चूंकि एक 32 बिट पूर्णांक का सकारात्मक अधिकतम 2,147,483,647 है, तो आपको एक अहस्ताक्षरित int का उपयोग करना चाहिए अगर आपको पता है कि यह a) कभी भी नकारात्मक नहीं होगा और b) 2,147,483,648 तक पहुंच सकता है। ज्यादातर मामलों में, डेटाबेस कुंजियों और काउंटरों सहित, मैं कभी भी इस प्रकार के नंबरों से संपर्क नहीं करूंगा, इसलिए मुझे चिंता करने के बारे में खुद को परेशान नहीं करना चाहिए कि क्या साइन बिट का उपयोग संख्यात्मक मान के लिए किया जाता है या संकेत को इंगित करने के लिए।

मैं कहूंगा: int का उपयोग तब तक करें जब तक कि आपको पता न हो कि आपको अहस्ताक्षरित int की आवश्यकता है।


2
जब मूल्यों के साथ काम करना जो अधिकतम मूल्यों तक पहुंच सकता है, तो आपको साइन की परवाह किए बिना पूर्णांक ओवरफ्लो के संचालन की जांच करना शुरू करना चाहिए। ये चेक आमतौर पर अहस्ताक्षरित प्रकारों के लिए आसान होते हैं, क्योंकि अधिकांश ऑपरेशनों में अपरिभाषित और कार्यान्वयन परिभाषित व्यवहार के बिना अच्छी तरह से परिभाषित परिणाम होते हैं।
सिक्योर

3

यह सादगी और विश्वसनीयता के बीच एक व्यापार है। जितने अधिक कीड़े संकलन समय पर पकड़े जाएंगे, उतने ही विश्वसनीय सॉफ्टवेयर। विभिन्न लोग और संगठन उस स्पेक्ट्रम के साथ विभिन्न बिंदुओं पर हैं।

यदि आप कभी भी Ada में कोई उच्च-विश्वसनीयता वाली प्रोग्रामिंग करते हैं, तो आप भिन्न प्रकार के चर जैसे पैरों की दूरी बनाम मीटर की दूरी, और संकलक के झंडे का उपयोग करते हैं यदि आप गलती से एक दूसरे को सौंप देते हैं। यदि आप एक वेब फ़ॉर्म को मान्य कर रहे हैं, तो निर्देशित मिसाइल की प्रोग्रामिंग के लिए एकदम सही है, लेकिन ओवरकिल (इच्छित उद्देश्य)। जब तक यह आवश्यकताओं को पूरा करता है, तब तक किसी भी तरह से कुछ भी गलत नहीं है।


2

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

इसी कारण से, मेरे पास कुछ चुनिंदा उदाहरणों में, SQL सर्वर तालिकाओं में (32-बिट पूर्णांक) के BIGINTबजाय (64 INTEGER-बिट पूर्णांक) का उपयोग किया गया है। डेटा के किसी भी उचित मात्रा के भीतर 32-बिट सीमा को हिट करने की संभावना न्यूनतम है, लेकिन अगर ऐसा होता है, तो कुछ स्थितियों में परिणाम काफी विनाशकारी हो सकते हैं। बस भाषाओं के बीच के प्रकारों को ठीक से मैप करना सुनिश्चित करें, या आप वास्तव में सड़क के नीचे दिलचस्प अजीबता के साथ समाप्त होने जा रहे हैं ...

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


यदि आप SAP सिस्टम से निकाले गए डेटा के साथ काम कर रहे हैं, तो मैं दृढ़ता से ID फ़ील्ड (जैसे कि CustomerNumber, ArticleNumber आदि) के लिए BIGINT की सलाह देता हूं। जब तक कोई भी आईडी के रूप में अल्फ़ान्यूमेरिक स्ट्रिंग्स का उपयोग नहीं करता है, तब तक ... आह
ट्रेब

1

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

प्राथमिक बार किसी को अहस्ताक्षरित प्रकारों का उपयोग करना चाहिए जब एक या तो एक से अधिक मानों को बड़े में जोड़ रहा होता है (जैसे चार बाइट्स को 32-बिट संख्या में बदलना) या बड़े मानों को छोटे में बदलना (जैसे कि चार बिट्स के लिए 32-बिट संख्या को संग्रहीत करना) ), या जब किसी के पास समय-समय पर "रोल ओवर" करने की उम्मीद होती है और उससे निपटने की आवश्यकता होती है (आवासीय उपयोगिता मीटर के बारे में सोचें, तो उनमें से अधिकांश के पास यह सुनिश्चित करने के लिए पर्याप्त अंक हैं कि वे संभवतः रीडिंग के बीच रोल नहीं करेंगे। यदि वे वर्ष में तीन बार पढ़ते हैं, लेकिन यह सुनिश्चित करने के लिए पर्याप्त नहीं है कि वे मीटर के उपयोगी जीवन में रोल नहीं करेंगे)। अनसाइन किए गए प्रकारों में अक्सर पर्याप्त 'विचित्रता' होती है कि उनका उपयोग केवल उन मामलों में किया जाना चाहिए जहां उनके शब्दार्थ आवश्यक हैं।


1
"मैं सुझाऊंगा [...] आम तौर पर हस्ताक्षरित प्रकारों का उपयोग करें।" हम्म, आप हस्ताक्षरित प्रकारों के फायदों का उल्लेख करना भूल गए हैं और केवल यह सूची दी है कि अहस्ताक्षरित प्रकारों का उपयोग कब करना है। "अजीबता" ? जबकि अधिकांश अहस्ताक्षरित कार्यों में अच्छी तरह से परिभाषित व्यवहार और परिणाम होते हैं, आप हस्ताक्षरित प्रकारों (अतिप्रवाह, बिट शिफ्ट, ...) का उपयोग करते समय अपरिभाषित और कार्यान्वयन परिभाषित व्यवहार दर्ज करते हैं। आपके यहाँ "अजीब" की एक अजीब परिभाषा है।
सिक्योर

1
@ सेक्योर: "विचित्रता" जिसका मैं उल्लेख करता हूं, तुलनात्मक ऑपरेटरों के शब्दार्थों के साथ करना है, विशेष रूप से उन कार्यों में, जिनमें मिश्रित हस्ताक्षरित और अहस्ताक्षरित प्रकार शामिल हैं। आप सही हैं कि अतिप्रवाह के मूल्यों का उपयोग करते समय हस्ताक्षरित प्रकारों का व्यवहार अपरिभाषित होता है, लेकिन अपेक्षाकृत छोटी संख्याओं से निपटने पर भी अहस्ताक्षरित प्रकारों का व्यवहार आश्चर्यजनक हो सकता है। उदाहरण के लिए, (-3) + (1u) -1 से अधिक है। इसके अलावा, कुछ सामान्य गणितीय साहचर्य संबंध जो संख्याओं पर लागू होंगे, वे अहस्ताक्षरित पर लागू नहीं होते हैं। उदाहरण के लिए, (ab)> c का अर्थ नहीं है (ac)> b।
सुपरकैट

1
@Secure: हालांकि यह सच है कि व्यक्ति हमेशा "बड़े" हस्ताक्षरित संख्याओं के साथ इस तरह के साहचर्यपूर्ण व्यवहार पर भरोसा नहीं कर सकता है, यह व्यवहार अपेक्षित संख्या के साथ काम करते समय अपेक्षित रूप से काम करते हैं जो हस्ताक्षरित पूर्णांकों के डोमेन के सापेक्ष "छोटे" होते हैं। इसके विपरीत, उपर्युक्त गैर-संघटित अहस्ताक्षरित मान "2 3 1" के साथ समस्याग्रस्त है। संयोग से, इस तथ्य पर हस्ताक्षर किए गए व्यवहार में अपरिभाषित व्यवहार होता है कि जब सीमा से बाहर का उपयोग किया जाता है तो मूल शब्द आकार से छोटे मूल्यों का उपयोग करते समय कुछ प्लेटफार्मों पर बेहतर कोड पीढ़ी के लिए अनुमति दे सकता है।
सुपरकैट

1
अगर आपके सुझाव बिना किसी कारण के, बिना किसी सिफारिश के और "नाम-पुकार" के बजाय, आपके उत्तर में होते, तो मैं यह टिप्पणी नहीं करता। ;) हालांकि मैं अभी भी "विचित्रता" से सहमत नहीं हूं, यह केवल प्रकार की परिभाषा है। दिए गए कार्य के लिए सही उपकरण का उपयोग करें, और उपकरण को जानें। अहस्ताक्षरित प्रकार गलत उपकरण हैं जब आपको +/- संबंधों की आवश्यकता होती है। एक कारण है कि क्यों size_tअहस्ताक्षरित है और ptrdiff_tहस्ताक्षरित है।
सुरक्षित

1
@ असुरक्षित: यदि कोई चाहता है कि बिट्स के अनुक्रम का प्रतिनिधित्व किया जाए, तो अहस्ताक्षरित प्रकार महान हैं; मुझे लगता है कि हम वहां सहमत हैं। और कुछ छोटे micros पर, अहस्ताक्षरित प्रकार संख्यात्मक मात्रा के लिए अधिक कुशल हो सकते हैं। वे उन मामलों में भी उपयोगी हैं जहां डेल्टास संख्यात्मक मात्रा का प्रतिनिधित्व करते हैं, लेकिन वास्तविक मान नहीं होते हैं (जैसे टीसीपी अनुक्रम संख्या)। दूसरी ओर, किसी भी समय एक के बिना अहस्ताक्षरित मानों को घटा देने से किसी को कोने के मामलों के बारे में चिंता करना पड़ता है, भले ही संख्या छोटी हो; हस्ताक्षरित मूल्यों वाले ऐसे गणित केवल कोने के मामलों को प्रस्तुत करते हैं जब संख्या बड़ी होती है।
Supercat

1

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

  • जब आप अपने अहस्ताक्षरित लघु चर और शाब्दिक (जो प्रकार int के होते हैं) या प्रकार int के चर के साथ अंकगणित करते हैं, तो यह सुनिश्चित करता है कि अभिव्यक्ति का मूल्यांकन करने से पहले अहस्ताक्षरित चर को हमेशा बढ़ावा दिया जाएगा, क्योंकि int की हमेशा शॉर्ट से उच्च रैंक होती है । यह हस्ताक्षरित और अहस्ताक्षरित प्रकारों के साथ अंकगणित करने वाले किसी भी अप्रत्याशित व्यवहार से बचा जाता है, यह मानते हुए कि अभिव्यक्ति का परिणाम एक हस्ताक्षरित पाठ्यक्रम में फिट बैठता है।
  • अधिकांश समय, आपके द्वारा उपयोग किया जा रहा अहस्ताक्षरित 2-बाइट शॉर्ट (65,535) के अधिकतम मान से अधिक नहीं होगा

सामान्य सिद्धांत यह है कि आपके अहस्ताक्षरित चर का प्रकार हस्ताक्षरित प्रकार को बढ़ावा देने के लिए हस्ताक्षरित चर के प्रकार से कम रैंक होना चाहिए। तब आपके पास कोई अप्रत्याशित अतिप्रवाह व्यवहार नहीं होगा। जाहिर है आप इसे हर समय सुनिश्चित नहीं कर सकते, लेकिन (अधिकतर) अक्सर यह सुनिश्चित करने के लिए संभव है।

उदाहरण के लिए, हाल ही में मैंने लूप के लिए कुछ इस तरह से किया था:

const unsigned short cuint = 5;
for(unsigned short i=0; i<10; ++i)
{
    if((i-2)%cuint == 0)
    {
       //Do something
    }
}

शाब्दिक '2' टाइप इंट का है। यदि मैं एक अहस्ताक्षरित लघु के बजाय एक अहस्ताक्षरित int था, तो उप-अभिव्यक्ति (i-2) में, 2 को एक अहस्ताक्षरित int में पदोन्नत किया जाएगा (चूंकि अहस्ताक्षरित int के पास हस्ताक्षरित int की तुलना में उच्च प्राथमिकता है)। यदि मैं = 0 है, तो उप-अभिव्यक्ति बराबर (0u-2u) = अतिप्रवाह के कारण कुछ बड़े मूल्य। I = 1 के साथ एक ही विचार। हालांकि, चूंकि मैं एक अहस्ताक्षरित छोटा है, इसलिए इसे उसी प्रकार प्रचारित किया जाता है जैसे कि शाब्दिक '2', जिसे इंट साइन किया गया है, और सब कुछ ठीक काम करता है।

अतिरिक्त सुरक्षा के लिए: उस दुर्लभ मामले में जहां आप जिस आर्किटेक्चर को लागू कर रहे हैं वह int 2 बाइट्स होने का कारण बनता है, इससे अंकगणितीय अभिव्यक्ति में दोनों ऑपरेंड का कारण उस मामले में अहस्ताक्षरित int को बढ़ावा दिया जा सकता है जहां अहस्ताक्षरित लघु चर फिट नहीं होता है हस्ताक्षरित 2-बाइट इंट में, जिसके बाद का अधिकतम मूल्य 32,767 <65,535 है। ( अधिक जानकारी के लिए https://stackoverflow.com/questions/17832815/c-implicit-conversion-signed-unsign देखें )। इसके विरुद्ध पहरा देने के लिए आप अपने प्रोग्राम में static_assert को इस प्रकार जोड़ सकते हैं:

static_assert(sizeof(int) == 4, "int must be 4 bytes");

और यह उन आर्किटेक्चर पर संकलन नहीं करेगा जहां int 2 बाइट्स है।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.