बग का कारण बनने के लिए हस्ताक्षरित इंट के बजाय एक अहस्ताक्षरित का उपयोग कर रहा है? क्यों?


82

में गूगल सी ++ स्टाइल गाइड , "अहस्ताक्षरित पूर्णांकों" के विषय पर, यह सुझाव दिया है कि

ऐतिहासिक दुर्घटना के कारण, C ++ मानक कंटेनरों के आकार का प्रतिनिधित्व करने के लिए अहस्ताक्षरित पूर्णांक का उपयोग करता है - मानक निकाय के कई सदस्य इसे गलती मानते हैं, लेकिन इस बिंदु पर इसे ठीक करना असंभव है। तथ्य यह है कि अहस्ताक्षरित अंकगणित एक साधारण पूर्णांक के व्यवहार को मॉडल नहीं करता है, लेकिन इसके बजाय मॉडल मॉड्यूलर अंकगणित (अतिप्रवाह / अंडरफ्लो पर चारों ओर लपेटने) के मानक द्वारा परिभाषित किया गया है, इसका मतलब है कि संकलक द्वारा बग के महत्वपूर्ण वर्ग का निदान नहीं किया जा सकता है।

मॉड्यूलर अंकगणित में क्या गलत है? एक अहस्ताक्षरित int का अपेक्षित व्यवहार नहीं है?

किस प्रकार के कीड़े (एक महत्वपूर्ण वर्ग) गाइड को संदर्भित करता है? अतिप्रवाह कीड़े?

एक अहस्ताक्षरित प्रकार का उपयोग केवल यह दावा करने के लिए न करें कि एक चर गैर-नकारात्मक है।

एक कारण यह है कि मैं हस्ताक्षरित int का उपयोग अहस्ताक्षरित int पर करने के बारे में सोच सकता हूं, यह है कि अगर यह अतिप्रवाह (नकारात्मक) करता है, तो इसका पता लगाना आसान है।


4
unsigned int x = 0; --x;जो xबनने की कोशिश करो और देखो । सीमा की जांच के बिना, आकार को अचानक कुछ अप्रत्याशित मूल्य मिल सकता है जो आसानी से यूबी तक ले जा सकता है।
कुछ प्रोग्रामर ने

33
कम से कम अहस्ताक्षरित अतिप्रवाह में एक अच्छी तरह से परिभाषित व्यवहार होता है और अपेक्षित परिणाम उत्पन्न करता है।
user7860670

35
एक असंबंधित (आपके प्रश्न के लिए लेकिन Google स्टाइलगाइड्स के लिए नहीं) ध्यान दें, यदि आप थोड़ी खोज करेंगे तो आपको Google स्टाइलगाइड्स की कुछ (कभी-कभी ही सही) आलोचना मिलेगी। उन्हें सुसमाचार के रूप में मत लो।
कुछ प्रोग्रामर ने

18
दूसरी ओर, intओवरफ्लो और अंडरफ्लो यूबी हैं। आपको ऐसी स्थिति का अनुभव होने की संभावना कम है जहां कोई intऐसा मान व्यक्त करने की कोशिश करेगा जो उस स्थिति से कम नहीं हो सकती है जो unsigned intनीचे के शून्य को घटाता है लेकिन जिस तरह के लोग unsigned intअंकगणित के व्यवहार से आश्चर्यचकित होंगे वे उस तरह के लोग हैं जो ऐसा भी कर सकते हैं intओवरफ़्लो की a < a + 1जाँच करने के लिए उपयोग करने से संबंधित यूबी ओवरफ़्लो का कारण बनने वाला कोड लिखें ।
फ्रांस्वा एंड्रीक्स

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

जवाबों:


71

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

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

अहस्ताक्षरित मानों में शून्य पर असंतोष है, प्रोग्रामिंग में सबसे आम मूल्य है

अहस्ताक्षरित और हस्ताक्षर किए गए पूर्णांक दोनों में उनके न्यूनतम और अधिकतम मूल्यों पर एक कटाव होता है, जहां वे चारों ओर लपेटते हैं (अहस्ताक्षरित) या अपरिभाषित व्यवहार (हस्ताक्षरित) का कारण बनते हैं। के लिए unsignedइन बिंदुओं पर कर रहे हैं शून्य और UINT_MAX। के लिए intवे कर रहे हैं INT_MINऔर INT_MAX। की विशिष्ट मूल्यों INT_MINऔर INT_MAX4 बाइट के साथ सिस्टम पर intमान हैं -2^31और 2^31-1, और एक ऐसी प्रणाली पर UINT_MAXआम तौर पर है 2^32-1

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

पिछले 0.5 को छोड़कर सूचकांक द्वारा वेक्टर के सभी मूल्यों पर कोड पुनरावृत्तियों पर विचार करें :

for (size_t i = 0; i < v.size() - 1; i++) { // do something }

यह ठीक काम करता है जब तक कि एक दिन आप एक खाली वेक्टर में नहीं गुजरते। शून्य पुनरावृत्तियों करने के बजाय, आपको v.size() - 1 == a giant number1 मिलता है और आप 4 बिलियन पुनरावृत्तियाँ करेंगे और लगभग एक बफर अतिप्रवाह भेद्यता होगी।

आपको इसे इस तरह लिखना होगा:

for (size_t i = 0; i + 1 < v.size(); i++) { // do something }

तो यह इस मामले में "तय" किया जा सकता है, लेकिन केवल बिना ध्यान दिए हुए प्रकृति के बारे में सोचकर size_t। कभी-कभी आप ऊपर दिए गए फ़िक्सेस को लागू नहीं कर सकते हैं क्योंकि एक स्थिर के बजाय आपके पास कुछ वैरिएबल ऑफ़सेट हैं जिन्हें आप लागू करना चाहते हैं, जो सकारात्मक या नकारात्मक हो सकता है: इसलिए तुलना के "पक्ष" जो आपको इसे लागू करने की आवश्यकता है, हस्ताक्षर पर निर्भर करता है - अब कोड वास्तव में गड़बड़ हो जाता है ।

कोड के साथ एक समान समस्या है जो शून्य तक और इसमें शामिल करने की कोशिश करता है। कुछ while (index-- > 0)ठीक काम करता है, लेकिन स्पष्ट रूप से समतुल्य while (--index >= 0)एक अहस्ताक्षरित मूल्य के लिए कभी समाप्त नहीं होगा। आपका कंपाइलर आपको चेतावनी दे सकता है जब दाहिने हाथ की ओर शाब्दिक शून्य है, लेकिन निश्चित रूप से नहीं अगर यह रनटाइम पर निर्धारित मूल्य है।

मुकाबला

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

कई लोग अहस्ताक्षरित के साथ "आप थोड़ा खो देंगे" का तर्क देंगे। यह अक्सर सच होता है - लेकिन हमेशा नहीं (यदि आपको अहस्ताक्षरित मूल्यों के बीच अंतर का प्रतिनिधित्व करने की आवश्यकता है तो आप उस बिट बिट को खो देंगे: तो कई 32-बिट चीजें 2 GiB तक सीमित हैं, या आपके पास एक अजीब ग्रे क्षेत्र होगा, जहां कहेंगे एक फ़ाइल 4 GiB हो सकती है, लेकिन आप दूसरे 2 GiB आधे पर कुछ API का उपयोग नहीं कर सकते हैं)।

यहां तक ​​कि उन मामलों में जहां अहस्ताक्षरित आपको थोड़ा खरीदता है: यह आपको ज्यादा नहीं खरीदता है: यदि आपको 2 बिलियन से अधिक "चीजों" का समर्थन करना था, तो आपको जल्द ही 4 बिलियन से अधिक का समर्थन करना होगा।

तार्किक रूप से, अहस्ताक्षरित मूल्य हस्ताक्षरित मूल्यों का सबसेट हैं

गणितीय रूप से, अहस्ताक्षरित मान (गैर-नकारात्मक पूर्णांक) हस्ताक्षरित पूर्णांक (बस _integers) कहा जाता है। । फिर भी हस्ताक्षर किए गए मान स्वाभाविक रूप से केवल अहस्ताक्षरित मानों, जैसे घटाव पर संचालन से बाहर निकलते हैं । हम कह सकते हैं कि अहस्ताक्षरित मान घटाव के तहत बंद नहीं हैं । हस्ताक्षरित मूल्यों का सच नहीं है।

एक फ़ाइल में दो अहस्ताक्षरित अनुक्रमित के बीच "डेल्टा" खोजना चाहते हैं? खैर आप सही क्रम में घटाव को बेहतर करते हैं, अन्यथा आपको गलत उत्तर मिलेगा। बेशक, आपको सही ऑर्डर निर्धारित करने के लिए अक्सर रनटाइम चेक की आवश्यकता होती है! जब संख्या के रूप में अहस्ताक्षरित मानों के साथ काम करते हैं, तो आप अक्सर पाएंगे कि (तार्किक रूप से) हस्ताक्षरित मूल्य वैसे भी दिखाई देते हैं, इसलिए आप हस्ताक्षर के साथ शुरू कर सकते हैं।

मुकाबला

जैसा कि ऊपर फुटनोट (2) में उल्लेख किया गया है, सी ++ में हस्ताक्षरित मूल्य वास्तव में एक ही आकार के अहस्ताक्षरित मूल्यों का एक उपसमूह नहीं हैं, इसलिए अहस्ताक्षरित मान उन परिणामों की समान संख्या का प्रतिनिधित्व कर सकते हैं जो हस्ताक्षर किए गए मान कर सकते हैं।

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

64-बिट संख्याओं के रूप में हस्ताक्षर किए गए मानों का उपयोग करने के कई कारणों से दरवाजा बंद कर देता है

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

विशेष डोमेन के बाहर 64-बिट मान काफी हद तक इस चिंता को दूर करते हैं। हस्ताक्षरित 64-बिट मानों की ऊपरी सीमा 9,223,372,036,854,775,807 - नौ क्विंटल से अधिक है । यह बहुत अधिक नैनोसेकंड (लगभग 292 साल), और बहुत सारा पैसा है। यह किसी भी कंप्यूटर की तुलना में एक बड़ी सरणी है जिसमें लंबे समय तक एक सुसंगत पते के स्थान में रैम होने की संभावना है। तो शायद 9 क्विंटल हर किसी के लिए पर्याप्त है (अभी के लिए)?

अहस्ताक्षरित मूल्यों का उपयोग कब करें

ध्यान दें कि स्टाइल गाइड निषिद्ध संख्याओं के उपयोग को मना या आवश्यक नहीं करता है। इसके साथ समाप्त होता है:

एक अहस्ताक्षरित प्रकार का उपयोग केवल यह दावा करने के लिए न करें कि एक चर गैर-नकारात्मक है।

वास्तव में, अहस्ताक्षरित चर के लिए अच्छे उपयोग हैं:

  • जब आप एन-बिट मात्रा को पूर्णांक के रूप में नहीं, बल्कि बस एक "बिट्स के बैग" के रूप में व्यवहार करना चाहते हैं। उदाहरण के लिए, एक बिटमास्क या बिटमैप या एन बुलियन मान या जो भी हो। यह उपयोग अक्सर निश्चित चौड़ाई प्रकारों के साथ हाथ से हाथ जाता है uint32_tऔर uint64_tचूंकि आप अक्सर चर के सटीक आकार को जानना चाहते हैं। एक संकेत है कि एक विशेष चर इस इलाज के हकदार है कि आप केवल के साथ साथ इस पर काम करते है बिटवाइज़ जैसे ऑपरेटरों ~, |, &, ^, >>और इतने पर, और नहीं अंकगणितीय आपरेशनों जैसे के साथ +, -, *, /आदि

    अनसाइनड यहाँ आदर्श है क्योंकि बिटवाइज़ ऑपरेटरों का व्यवहार अच्छी तरह से परिभाषित और मानकीकृत है। हस्ताक्षर किए गए मानों में कई समस्याएं हैं, जैसे कि स्थानांतरण के समय अपरिभाषित और अनिर्दिष्ट व्यवहार और एक अनिर्दिष्ट प्रतिनिधित्व।

  • जब आप वास्तव में मॉड्यूलर अंकगणित चाहते हैं। कभी-कभी आप वास्तव में 2 ^ एन मॉड्यूलर अंकगणित चाहते हैं। इन मामलों में "अतिप्रवाह" एक विशेषता है, बग नहीं। अहस्ताक्षरित मान आपको वही देते हैं जो आप यहां चाहते हैं क्योंकि वे मॉड्यूलर अंकगणित का उपयोग करने के लिए परिभाषित किए गए हैं। क्योंकि वे एक अनिर्दिष्ट प्रतिनिधित्व है और अतिप्रवाह अपरिभाषित है पर हस्ताक्षरित मान (आसानी से, कुशलता से) का उपयोग नहीं किया जा सकता है।


०.५ मैंने इसे लिखने के बाद महसूस किया कि यह जैरोड के उदाहरण के लगभग समान है , जिसे मैंने नहीं देखा था - और अच्छे कारण के लिए, यह एक अच्छा उदाहरण है!

1 हम size_tयहां बात कर रहे हैं आमतौर पर 2 ^ 32-1 एक 32-बिट सिस्टम पर या 2 ^ 64-1 64-बिट एक पर।

2 सी + + में यह बिल्कुल मामला नहीं है क्योंकि अहस्ताक्षरित मानों में संबंधित हस्ताक्षरित प्रकार की तुलना में ऊपरी छोर पर अधिक मूल्य होते हैं, लेकिन मूल समस्या मौजूद है कि अहस्ताक्षरित मानों में हेरफेर करने के परिणामस्वरूप (तार्किक रूप से) हस्ताक्षरित मान हो सकते हैं, लेकिन कोई संगत मुद्दा नहीं है। हस्ताक्षरित मूल्यों के साथ (क्योंकि हस्ताक्षरित मूल्यों में पहले से ही अहस्ताक्षरित मूल्य शामिल हैं)।


10
मैं आपके द्वारा पोस्ट की गई हर चीज से सहमत हूं, लेकिन "64 बिट्स सभी के लिए पर्याप्त होना चाहिए" यकीन है कि रास्ता बहुत करीब है "640k सभी के लिए पर्याप्त होना चाहिए"।
एंड्रयू हेनले

6
@ और - हाँ, मैंने अपने शब्दों को ध्यान से चुना :)।
BeeOnRope

4
"64-बिट अहस्ताक्षरित मूल्यों पर दरवाजा बंद कर देता है" -> असहमत। कुछ पूर्णांक प्रोग्रामिंग कार्य सरल हैं, गिनती का मामला नहीं है और नकारात्मक मूल्यों की आवश्यकता नहीं है, फिर भी पावर-ऑफ -2 चौड़ाई की आवश्यकता है: पासवर्ड, एन्क्रिप्शन, बिट ग्राफिक्स, अहस्ताक्षरित गणित के साथ लाभ। यहां कई विचार इंगित करते हैं कि कोड सक्षम होने पर हस्ताक्षरित गणित का उपयोग क्यों कर सकता है, फिर भी अहस्ताक्षरित प्रकार को बेकार बनाने और उन पर दरवाजा बंद करने से बहुत कम हो जाता है।
chux -

2
@ डेडप्लिकेटर - हाँ, मैंने इसे छोड़ दिया क्योंकि यह टाई की तरह कम या ज्यादा लगता है। अहस्ताक्षरित mod-2 ^ N रैपराउंड की ओर से आप कम से कम एक परिभाषित व्यवहार करते हैं और कोई अप्रत्याशित "अनुकूलन किक नहीं करेगा। UB के पक्ष में, अहस्ताक्षरित या हस्ताक्षरित अंकगणित के दौरान किसी भी अतिप्रवाह को संभवतः भारी बहुमत में बग है। मामलों की (कुछ जो आधुनिक अंकगणित की उम्मीद से बाहर), और कंपाइलर ऐसे विकल्प प्रदान करते हैं जो -ftrapvसभी हस्ताक्षरित अतिप्रवाह को पकड़ सकते हैं, लेकिन सभी अहस्ताक्षरित अतिप्रवाह नहीं। प्रदर्शन प्रभाव बहुत बुरा नहीं है, इसलिए -ftrapvकुछ परिदृश्यों के साथ संकलन करना उचित हो सकता है।
BeeOnRope

2
@BeeOnRope That's about the age of the universe measured in nanoseconds.मुझे संदेह है कि। ब्रह्मांड 13.7*10^9 yearsपुराना है जो है 4.32*10^17 sया है 4.32*10^26 ns4.32*10^26इंट के रूप में प्रतिनिधित्व करने के लिए आपको कम से कम की आवश्यकता है 90 bits9,223,372,036,854,775,807 nsके बारे में ही होगा 292.5 years
ओसिरिस

37

जैसा कि कहा गया है, मिश्रण unsignedऔर signedअप्रत्याशित व्यवहार को जन्म दे सकता है (भले ही अच्छी तरह से परिभाषित हो)।

मान लीजिए कि आप पिछले पांच को छोड़कर वेक्टर के सभी तत्वों पर चलना चाहते हैं, तो आप गलत तरीके से लिख सकते हैं:

for (int i = 0; i < v.size() - 5; ++i) { foo(v[i]); } // Incorrect
// for (int i = 0; i + 5 < v.size(); ++i) { foo(v[i]); } // Correct

मान लीजिए v.size() < 5, फिर, जैसा कि v.size()है unsigned, s.size() - 5एक बहुत बड़ी संख्या होगी, और इसलिए मूल्य के अधिक अपेक्षित रेंज के लिए i < v.size() - 5होगा । और UB तब जल्दी से होता है (एक बार बाउंड एक्सेस से बाहर )trueii >= v.size()

यदि v.size()हस्ताक्षरित मूल्य वापस होगा, तो s.size() - 5नकारात्मक होगा, और उपरोक्त मामले में, स्थिति तुरंत झूठी होगी।

दूसरी तरफ, सूचकांक के बीच होना चाहिए [0; v.size()[इसलिए unsignedसमझ में आता है। एक हस्ताक्षरित नकारात्मक संख्या के सही बदलाव के लिए अतिप्रवाह या कार्यान्वयन-परिभाषित व्यवहार के साथ हस्ताक्षरित UB के रूप में अपना स्वयं का मुद्दा भी है, लेकिन पुनरावृत्ति के लिए बग का कम लगातार स्रोत।


2
जब भी मैं स्वयं हस्ताक्षरित संख्याओं का उपयोग करता हूं, जब भी मैं कर सकता हूं, मुझे नहीं लगता कि यह उदाहरण पर्याप्त मजबूत है। कोई जो लंबे समय तक अहस्ताक्षरित संख्याओं का उपयोग करता है, निश्चित रूप से इस मुहावरे को जानता है: इसके बजाय i<size()-X, किसी को लिखना चाहिए i+X<size()। निश्चित रूप से, यह याद रखने वाली बात है, लेकिन ऐसा नहीं है कि मेरी राय में आदी होना मुश्किल है।
जेजा

8
आप जो कह रहे हैं, वह मूल रूप से भाषा और प्रकारों के बीच ज़बरदस्ती के नियमों को जानना है। मैं यह नहीं देखता कि यह कैसे बदलता है कि क्या कोई हस्ताक्षरित या अहस्ताक्षरित का उपयोग करता है जैसा कि प्रश्न पूछता है। ऐसा नहीं है कि मैं नकारात्मक मूल्यों की आवश्यकता नहीं है, तो मैं बिल्कुल भी हस्ताक्षरित का उपयोग करने की सलाह देता हूं। मैं @geza से सहमत हूं, केवल आवश्यक होने पर हस्ताक्षरित का उपयोग करें । यह google गाइड को सबसे अच्छे से संदिग्ध बनाता है । Imo यह बुरी सलाह है।
इस साइट

2
@toohonestforthissite इस बिंदु नियम चाप, चुप और कीड़े के प्रमुख कारण हैं। अंकगणित के लिए विशेष रूप से हस्ताक्षरित प्रकारों का उपयोग करना आपको समस्या से छुटकारा दिलाता है। सकारात्मक मूल्यों को लागू करने के उद्देश्य से अहस्ताक्षरित प्रकारों का उपयोग करने वाले BTW उनके लिए सबसे खराब दुरुपयोग में से एक है।
राहगीर

2
शुक्र है, आधुनिक संकलक और आईडीई एक अभिव्यक्ति में हस्ताक्षरित और अहस्ताक्षरित संख्याओं को मिलाते समय चेतावनी देते हैं।
एलेक्सी बी।

5
@PasserBy: यदि आप उन्हें आर्कन कहते हैं, तो आपको हस्ताक्षरित प्रकार के आर्कन के अतिप्रवाह के लिए पूर्णांक पदोन्नति और यूबी को भी जोड़ना होगा। और बहुत ही सामान्य sizeof ऑपरेटर एक अहस्ताक्षरित वैसे भी देता है, तो आप की क्या ज़रूरत है उनके बारे में पता है। कहा कि: यदि आप भाषा का विवरण नहीं सीखना चाहते हैं, तो केवल C या C ++ का उपयोग न करें! Google को ध्यान में रखते हुए, हो सकता है कि # लक्ष्य बिल्कुल उनके लक्ष्य का हो। "बुरे मत बनो" के दिन लंबे हो गए हैं ...
इस साइट के लिए बहुत ही ईमानदार है

20

त्रुटि के सबसे अधिक बालों को बढ़ाने वाले उदाहरणों में से एक है जब आपने MIX हस्ताक्षरित और अहस्ताक्षरित मान:

#include <iostream>
int main()  {
    auto qualifier = -1 < 1u ? "makes" : "does not make";
    std::cout << "The world " << qualifier << " sense" << std::endl;
}

उत्पादन:

दुनिया को इससे कोई मतलब नहीं है

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

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


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

1
@ user7586189 अमान्य डेटा को तुरंत करना असंभव बनाने के लिए एक अच्छा अभ्यास है, इसलिए आकार के लिए केवल सकारात्मक चर होना पूरी तरह से उचित है। लेकिन आप इस उत्तर में डिफ़ॉल्ट खराब कलाकारों द्वारा अस्वीकृत करने के लिए C / C ++ बिल्ट-इन प्रकारों को ठीक नहीं कर सकते हैं और वैधता किसी और की जिम्मेदारी बन जाती है। यदि आप कड़ी जातियों वाली भाषा में हैं (बिल्ट-इन के बीच भी), तो अपेक्षित डोमेन मॉडलिंग बहुत अच्छा विचार है।
विलास

1
ध्यान दें, मैंने चेतावनियों को क्रैंक करने और उन्हें त्रुटियों पर सेट करने का उल्लेख किया था , लेकिन हर कोई ऐसा नहीं करता है। मैं अभी भी मॉडलिंग मूल्यों के बारे में आपके बयान से @villasv असहमत हूं। अहस्ताक्षरित का चयन करके, आप यह भी कह रहे हैं कि हर दूसरे मूल्य के बारे में मॉडलिंग करने से यह पता चल सकता है कि क्या होगा। और लगभग निश्चित रूप से यह गलत हो रहा है।
क्रिस उज़ाद्विनियां

1
मन में डोमेन के साथ मॉडलिंग एक अच्छी बात है। डोमेन का उपयोग करने के लिए अहस्ताक्षरित का उपयोग करना नहीं है। (हस्ताक्षरित बनाम अहस्ताक्षरित को उपयोग के प्रकारों के आधार पर चुना जाना चाहिए , मूल्यों की श्रेणी नहीं , जब तक कि यह अन्यथा करना असंभव न हो।)
क्रिस ज़ुडाविंसिन

2
एक बार जब आपके कोडबेस में हस्ताक्षरित और अहस्ताक्षरित मूल्यों का मिश्रण होता है, जब आप चेतावनी देते हैं और उन्हें त्रुटियों को बढ़ावा देते हैं, तो रूपांतरण को स्पष्ट करने के लिए कोड static_casts के साथ समाप्त हो जाता है (क्योंकि गणित को अभी भी करने की आवश्यकता है।) यहां तक ​​कि सही भी। यह त्रुटिपूर्ण है, साथ काम करना कठिन है, और पढ़ने में कठिन है।
क्रिस ज़ुदाविंसिन

11

एक हस्ताक्षरित int का उपयोग करने की तुलना में बग के कारण बग के लिए अहस्ताक्षरित int का उपयोग करने की अधिक संभावना क्यों है?

एक अहस्ताक्षरित प्रकार का उपयोग करने से कुछ प्रकार के कार्यों के साथ हस्ताक्षरित प्रकार का उपयोग करने की तुलना में बग पैदा होने की अधिक संभावना नहीं है।

इस काम के लिए सही उपकरण का उपयोग करें।

मॉड्यूलर अंकगणित में क्या गलत है? एक अहस्ताक्षरित int का अपेक्षित व्यवहार नहीं है?
एक हस्ताक्षरित int का उपयोग करने की तुलना में बग के कारण बग के लिए अहस्ताक्षरित int का उपयोग करने की अधिक संभावना क्यों है?

यदि कार्य अच्छी तरह से मेल खाता है: कुछ भी गलत नहीं है। नहीं, अधिक संभावना नहीं है।

सुरक्षा, एन्क्रिप्शन, और प्रमाणीकरण एल्गोरिथ्म अहस्ताक्षरित मॉड्यूलर गणित पर भरोसा करते हैं।

संपीड़न / अपघटन एल्गोरिदम भी और साथ ही विभिन्न ग्राफिक प्रारूप लाभान्वित होते हैं और अहस्ताक्षरित गणित के साथ कम छोटी गाड़ी होती है ।

किसी भी समय बिट-वार ऑपरेटरों और पारियों का उपयोग किया जाता है, बिना हस्ताक्षर किए गए हस्ताक्षरित गणित के साइन-एक्सटेंशन मुद्दों के साथ गड़बड़ नहीं होते हैं ।


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

हस्ताक्षरित गणित का एक नुकसान आज सर्वव्यापी 32-बिट है intजो इतनी सारी समस्याओं के साथ - साथ आम कार्यों के लिए काफी हद तक व्यापक है। यह शालीनता की ओर जाता है कि अतिप्रवाह के खिलाफ कोड नहीं किया गया है। इसके बजाय, for (int i=0; i < n; i++) int len = strlen(s);ओके के रूप में देखा जाता है क्योंकि nयह माना जाता है कि < INT_MAXऔर स्ट्रिंग्स कभी भी बहुत लंबे नहीं होंगे, बजाय पहले मामले में पूर्ण रक्षित या उपयोग किए गए size_t, unsignedया यहां तक long longकि 2 में संरक्षित ।

C / C ++ एक ऐसे युग में विकसित हुआ जिसमें 16-बिट के साथ-साथ 32-बिट भी शामिल थे intऔर अतिरिक्त बिट्स का एक बिट-बिट size_tप्रतिरूप महत्वपूर्ण था। समस्याओं के अतिप्रवाह के संबंध में ध्यान देने की आवश्यकता थी intया यह हो सकता है unsigned

गैर-16 बिट int/unsignedप्लेटफार्मों पर Google के 32-बिट (या व्यापक) अनुप्रयोगों के साथ , intइसकी पर्याप्त रेंज के +/- ओवरफ्लो पर ध्यान देने की कमी को हल करता है । यह इस तरह के अनुप्रयोगों को intखत्म करने के लिए प्रोत्साहित करता है unsigned। फिर भी intगणित अच्छी तरह से संरक्षित नहीं है।

संकीर्ण 16-बिट int/unsignedचिंताएं आज चुनिंदा एम्बेडेड अनुप्रयोगों के साथ लागू होती हैं।

Google के दिशानिर्देश उस कोड के लिए अच्छी तरह से लागू होते हैं जो वे आज लिखते हैं। यह C / C ++ कोड के बड़े दायरे के लिए एक निश्चित दिशानिर्देश नहीं है।


एक कारण यह है कि मैं हस्ताक्षरित int का उपयोग अहस्ताक्षरित int पर करने के बारे में सोच सकता हूं, यह है कि अगर यह अतिप्रवाह (नकारात्मक) करता है, तो इसका पता लगाना आसान है।

C / C ++ में, हस्ताक्षरित इंट गणित अतिप्रवाह अपरिभाषित व्यवहार है और इसलिए अहस्ताक्षरित गणित के परिभाषित व्यवहार की तुलना में निश्चित रूप से पता लगाना आसान नहीं है ।


जैसा कि @Chris उज़ाद्विनियों ने अच्छी तरह से टिप्पणी की है, हस्ताक्षरित और अहस्ताक्षरित मिश्रण को सभी (विशेषकर शुरुआती) से बचा जाता है और अन्यथा जरूरत पड़ने पर सावधानी से कोडित किया जाता है।


2
आप एक अच्छा बिंदु बनाते हैं intजो "वास्तविक" पूर्णांक के व्यवहार को मॉडल नहीं करता है। अतिप्रवाह पर अनिर्धारित व्यवहार यह नहीं है कि गणितज्ञ पूर्णांकों के बारे में कैसे सोचते हैं: वे एक पूर्णांक के साथ "अतिप्रवाह" की कोई संभावना नहीं हैं। लेकिन ये मशीन स्टोरेज यूनिट हैं, गणित के आदमी के नंबर नहीं।
tchrist

1
@tchrist: ओवरफ्लो पर अनसाइन किया गया व्यवहार यह है कि एक गणितज्ञ कैसे पूर्णांक अभिजात वर्ग के अभिजात वर्ग के रिंग के बारे में सोचता है, जो अनुरूप मॉड (type_MAX + 1) है।
सुपरकैट

यदि आप gcc का उपयोग कर रहे हैं, तो signed intअतिप्रवाह का पता लगाना आसान है (साथ -ftrapv), जबकि अहस्ताक्षरित "अतिप्रवाह" का पता लगाना कठिन है।
अनातोलीग

5

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

यदि आप उनके साथ अंकगणित करने की कोशिश करते हैं (तो क्रिस उज़ाद्विनियाँ ऊपर देखें), यदि आप उन्हें संख्याओं के रूप में उपयोग करते हैं, तो त्रुटिपूर्ण प्रकार से त्रुटियां होती हैं। अनसाइन किए गए प्रकारों का उपयोग संख्यात्मक मात्राओं को संग्रहीत करने के लिए उपयोग नहीं किया जाता है, उनका उद्देश्य ऐसे कंटेनरों के आकार की गणना करना है , जो कभी भी नकारात्मक नहीं हो सकते, और उनका उपयोग उस उद्देश्य के लिए किया जा सकता है।

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


जब मैं आपका बहाव प्राप्त करता हूं, तो किए गए कंबल बयान लगभग बिटवाइज़ ऑपरेशंस को समाप्त कर देंगे यदि unsignedप्रकार केवल गिनती पकड़ सकते हैं और अंकगणित में उपयोग नहीं किए जा सकते हैं। तो "खराब निर्देशकों से पागल निर्देश" भाग अधिक समझ में आता है।
डेविड सी। रंकिन

@ DavidC.Rankin कृपया इसे "कंबल" कथन के रूप में न लें। जाहिर है कि अहस्ताक्षरित पूर्णांकों के लिए कई वैध उपयोग हैं (जैसे बिटवाइज़ मानों को संग्रहीत करना)।
टायलर डरडेन

हां, हां - मैंने ऐसा नहीं किया, इसलिए मैंने कहा "मुझे आपका बहाव मिल गया है।"
डेविड सी। रंकिन

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

1
"त्रुटियां केवल अहस्ताक्षरित प्रकारों के साथ होती हैं यदि आप उनके साथ अंकगणित करने की कोशिश करते हैं" - जो हर समय होता है। "कंटेनर आकार को संग्रहीत करने के लिए अंकगणितीय प्रकार (जैसे हस्ताक्षरित पूर्णांक) का उपयोग करने का विचार मूर्खतापूर्ण है" - ऐसा नहीं है और C ++ समिति अब इसे size_t का उपयोग करने के लिए एक ऐतिहासिक गलती मानती है। कारण? सम्यक रूपांतरण।
टीला नेव्स

1

गैर-नकारात्मक मानों का प्रतिनिधित्व करने के लिए अहस्ताक्षरित प्रकारों का उपयोग करना ...

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

Google कोडिंग दिशानिर्देश पहली तरह के विचार पर जोर देता है। अन्य दिशानिर्देश सेट, जैसे कि C ++ कोर दिशानिर्देश , दूसरे बिंदु पर अधिक जोर देते हैं। उदाहरण के लिए, कोर दिशानिर्देश I.12 पर विचार करें :

I.12: एक ऐसे पॉइंटर की घोषणा करें जो कि अशक्त नहीं होना चाहिए not_null

कारण

डेलीफ्रेंसिंग nullptr त्रुटियों से बचने में मदद करने के लिए। के लिए निरर्थक चेकों से बचने के प्रदर्शन में सुधार करने nullptr

उदाहरण

int length(const char* p);            // it is not clear whether length(nullptr) is valid
length(nullptr);                      // OK?
int length(not_null<const char*> p);  // better: we can assume that p cannot be nullptr
int length(const char* p);            // we must assume that p can be nullptr

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

बेशक, आप non_negativeपूर्णांकों के लिए एक आवरण के लिए तर्क कर सकते हैं, जो त्रुटियों की दोनों श्रेणियों से बचता है, लेकिन इसके अपने मुद्दे होंगे ...


0

Google स्टेटमेंट कंटेनर के लिए एक आकार प्रकार के रूप में अहस्ताक्षरित का उपयोग करने के बारे में है । इसके विपरीत, प्रश्न अधिक सामान्य प्रतीत होता है। कृपया इसे ध्यान में रखें, जबकि आप पढ़ते हैं।

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

कंटेनर के आकार पर हस्ताक्षर किए

चलो मान लेते हैं कि किसी ने बग को कोडित किया है, जिसके परिणामस्वरूप एक नकारात्मक कंटेनर इंडेक्स होता है। परिणाम या तो अपरिभाषित व्यवहार है या अपवाद / पहुंच उल्लंघन है। क्या यह वास्तव में अपरिभाषित व्यवहार या अपवाद / पहुंच उल्लंघन से बेहतर है जब सूचकांक प्रकार अहस्ताक्षरित था? मेरे ख़्याल से नहीं।

अब, ऐसे लोगों का एक वर्ग है जो गणित के बारे में बात करना पसंद करते हैं और इस संदर्भ में "प्राकृतिक" क्या है। नकारात्मक संख्या के साथ एक अभिन्न प्रकार किसी चीज़ का वर्णन करने के लिए स्वाभाविक कैसे हो सकता है, जो स्वाभाविक रूप से> = 0 है? नकारात्मक आकारों के साथ सरणियों का उपयोग करना? IMHO, विशेष रूप से गणितीय रूप से इच्छुक लोगों को यह शब्दार्थ का बेमेल आकार (आकार / सूचकांक प्रकार कहता है कि नकारात्मक संभव है, जबकि एक नकारात्मक आकार की सरणी की कल्पना करना कठिन है) परेशान है।

तो, केवल एक ही सवाल, इस मामले पर शेष है अगर - जैसा कि Google टिप्पणी में कहा गया है - एक संकलक वास्तव में इस तरह के कीड़े को खोजने में सक्रिय रूप से सहायता कर सकता है। और विकल्प से भी बेहतर, जो कि बिना सोचे-समझे संरक्षित पूर्णांक (x86-64 असेंबली) के अंडरफ़्लो होगा और शायद अन्य आर्किटेक्चर के पास इसे प्राप्त करने का साधन है, केवल C / C ++ उन साधनों का उपयोग नहीं करता है)। एक ही तरीका है कि मैं थाह कर सकता हूं, यदि कंपाइलर स्वचालित रूप से रन टाइम चेक ( if (index < 0) throwOrWhatever) जोड़ देता है या संकलित समय क्रियाओं के मामले में संभावित रूप से गलत सकारात्मक चेतावनी / त्रुटियां उत्पन्न करता है "इस सरणी पहुंच के लिए सूचकांक नकारात्मक हो सकता है।" मुझे अपने संदेह हैं, यह मददगार होगा।

इसके अलावा, जो लोग वास्तव में अपने सरणी / कंटेनर सूचकांकों के लिए रनटाइम चेक लिखते हैं, यह हस्ताक्षरित पूर्णांक से निपटने के लिए अधिक काम है। लिखने के बजाय if (index < container.size()) { ... }अब आपको लिखना होगा if (index >= 0 && index < container.size()) { ... }:। लगता है कि मेरे लिए मज़दूर मजबूर हैं और सुधार की तरह नहीं ...

अहस्ताक्षरित प्रकारों के बिना भाषाएँ चूसना ...

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

इस मामले पर मेरे 5 सेंट हैं।

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